個人檔案共享空间标题相片部落格清單 工具 說明
31 October

环形公路难题

环形公路不均匀分布n个加油站,所有加油站的油加起来正好够一圈,油箱一开始为
空的,容量不限,且耗油均匀,问那个加油站出发可以跑完一圈
 
这个问题好像是via的c++笔试题目。我想了好久(~1h),觉得:
 
其实这个问题可以衍生为:
 
1. 跑完全程的路线是否一定存在
2. 如果正向存在,反向是否一定存在
3. 怎么找到起点加油站,如果有很多起点都可以跑完,怎么找到所有的起点
 
我的解答参回复。谁有好的想法尽管发啊
 
 
======================================
仔细考虑了一下,我第一次回复的算法不妥,下班后在公交车上就开始想,到现在终于想到一个比较完满的做法

我们应该这样考虑
假设这个圆周上有4个点,分别是A,B,C,D
A1表示A这点油库可以跑的路程
A2表示A这点到下一点(B)的路程
令AA=A1-A2
依次类推,BB=B1-B2, CC=C1-C2, DD=D1-D2
到了最后,我们就有AA,BB,CC,DD四个数据
由于A1+B1+C1+D1=A2+B2+C2+D2, 所以有:
AA+BB+CC+DD=0
假设我们从A出发,能够顺利以D结束,我们就需要满足:
A1-A2>=0 (AA>=0)
A1-A2+B1-B2>=0 (AA+BB>=0)
A1-A2+B1-B2+C1-C2>=0 (AA+BB+CC>=0)
当然,上面只是假设.其实我们真正需要做的,是在AA,BB,CC,DD这四个数据中,找满足下面任意一种条件:
1. AA>=0 AA+BB>=0 AA+BB+CC>=0
2. BB>=0 BB+CC>=0 BB+CC+DD>=0
3. CC>=0 CC+DD>=0 CC+DD+AA>=0
4. DD>=0 DD+AA>=0 DD+AA+BB>=0
只要找到了,我们就可以从相关的点出发.比如我们找到满足条件3, 我们就可以从C点出发

好了,剩下来的方法就是如何高效地找到这个点.如果我们注意观察,其实算法很简单:
从AA开始,分别计算AA, AA+BB,AA+BB+CC. 如果其中某一次计算的结果<0, 直接跳到下一个数据.比如我们发现AA+BB+CC<0, 由于前面已经AA+BB>=0已经通过,所以CC必然<0, 由于CC<0, 我们肯定不能够用C作起点,所以我们就直接从CC的下一个数据,DD开始计算. 当找到可以满足条件的结果后,我们就找到了起点. 从这个算法可以看到,效率是o(n), 一次循环就搞定了.

当然,如果你还想提高效率,我们还可以做努力.我们假设AA,BB,CC,DD都不等于0, 也就是说他们或正或负。我们可以很简地得出,起点肯定是在由负变正的时候产生。所以我们在选择起点的时候,通过这个方法可以平均淘汰掉大约3/4的点

也就是说,算法可以表示如下:

1. 假设加油站分布在N1,N2..Nn点上,N1(1)表示N1这点油库可以跑的路程,N1(2)表示N1这点到下一点(N2)的路程,令NN1=N1(1)-N1(2),依次类推
2. 将NN1,NN2,..NNn放入环形链表中
3. 从NN1开始,计算NN1,NN1+NN2,...一直到NN1+NN2+..+NNn.
4. 在第三步,如果有NN1+NN2+..+NNx<0, 以NNx+1开始,重复第三步计算
5. 环形链表跑完以后,得到由NNx开始的所有计算结果>=0, 那么起点就是Nx这点
有人有兴趣用C来实现一把么?

回應 (13)

請稍候...
很抱歉,您輸入的回應過長。請縮短您的回應。
您尚未輸入內容,請再試一次。
很抱歉,目前無法新增您的回應,請稍後再試。
若要新增回應,您的父母必須先給您權限。要求權限
您的家長已關閉回應功能。
很抱歉,目前無法刪除您的回應,請稍後再試。
您已超過每日回應上限次數,請於 24 小時後再試一次。
由於系統顯示您可能傳送垃圾郵件給其他使用者,因此您帳號中的回應功能已遭停用。 如果您認為自己帳號遭錯誤停用,請連絡 Windows Live 支援
請完成下列安全檢查,以完成回應。
您輸入的安全檢查字元必須與圖片或音訊中的字元相符。

若要新增回應,請以您的 Windows Live ID 登入 (若您使用 Hotmail、Messenger 或 Xbox LIVE,則您已擁有 Windows Live ID)。登入


沒有 Windows Live ID?註冊

9 月 8 日
沒有名稱撰寫:

Amberdigital Branch,Southern Stars Enterprises Co is specializing in the development and manufacturing of advertising displays, advertising player and LCD displays. Established in 1996, we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

amberdigital Contact Us
Southern Stars Enterprises Co (Hong Kong Office)
Add:3 Fl, No.2, Lane 2, Kam Tsin Tsuen, Sheung Shui, Hong Kong
Tel:+852 2681 4099
Fax:+852 2681 4586

Southern Stars Enterprises Co (Shenzhen Office)
Add:DE, 16/F, Building 2, Nanguo Tower, Sungang Road, Shenzhen, China
Tel:+86 755 2592 9100
Fax:+86 755 2592 7171

E-mail:sstar@netvigator.com
website:www.amberdigital.com.hk
alibaba:amberdigital.en.alibaba.com[ca

8 月 28 日
沒有名稱撰寫:
wow gold!All wow gold US Server 24.99$/1000G on sell! Cheap wow gold,wow gold,wow gold,Buy Cheapest/Safe/Fast WoW US EU wow gold Power leveling wow gold from the time you World of Warcraft gold ordered! wow power leveling wow power leveling power leveling wow power leveling wow powerleveling wow power levelingcheap wow power leveling wow power leveling buy wow power leveling wow power leveling buy power leveling wow power leveling cheap power leveling wow power leveling wow power leveling wow power leveling wow powerleveling wow power leveling power leveling wow power leveling wow powerleveling wow power leveling buy rolex cheap rolex wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow gold wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling wow power leveling -317795810896684
6 月 21 日
1 月 17 日
匿名 的圖片
putaoefu 撰寫:
我看了你得代码的
但是我看到两个嵌套的 for循环,效率就应该是 o(n^2)了,所以就没仔细看了。
11 月 1 日
匿名 的圖片
Johnny-Aya-Baiken 撰寫:
你还真敬业.......受小弟一拜......
-_-|||不过怎么不看一下我一开始发的伪代码呀......和你的想法是一样的.........(只是continue写错了.....失误.....)
11 月 1 日
匿名 的圖片
Johnny-Aya-Baiken 撰寫:
me:但是我不明白,你怎么找到所有可行路径....
引用:
下面是我关于如何找到其中一个起点加油站的想法:
....

-_-||||
sorry,又漏看了...............挖地洞把自己埋了算了......
10 月 31 日
匿名 的圖片
Johnny-Aya-Baiken 撰寫:
-_-|||||
sorry....看错你的算法........

但是我不明白,你怎么找到所有可行路径....
10 月 31 日
匿名 的圖片
putaoefu 撰寫:
可是你的方法只是解决如何建立加油站而不是在已有的加油站中找出可行的路径....

我的方法是找出可行路径,不是建立加油站
10 月 31 日
匿名 的圖片
Johnny-Aya-Baiken 撰寫:
可是你的方法只是解决如何建立加油站而不是在已有的加油站中找出可行的路径....
另外...我的方法没考虑逆时针...
10 月 31 日
匿名 的圖片
putaoefu 撰寫:
你忘了考虑假设a站到b站油多了,而b站到c站的油不够,但是a站到c站的油够跑这样的情况

考虑到这个情况的。我就是用的这样的例子来发现结果的。
10 月 31 日
匿名 的圖片
Johnny-Aya-Baiken 撰寫:
你忘了考虑假设a站到b站油多了,而b站到c站的油不够,但是a站到c站的油够跑这样的情况。题目说油箱容量不限。而且我认为油站是一开始就利用随机函数不均匀分布好的。

float total_oil = XXXXX;
float total_distance = XXXXXX;
float oil_per_distance = total_oil/total_distance;

struct station
{
station* prev;
station* next;
float position;
float oil;
};

main()
{
station staions[n] = CreateRandStation( seed );
for( all station )
assert( station[i].positon >= 0 && station[i].position < total_distance );

float distance = 0.0f;
for( int i = 0; i < n; ++i )
{
float accum_oil = 0.0f;
for( int j = i; station[j] != station[i]; ++j )
{
accum_oil += station[j].oil;
distance = station[j].position - station[i].position;
if( distance * oil_per_distance > accum_oil )
continue;
}
RecordThisStation( i );
}

DisplayPossibleStations();
}

这个方法很土,可以用数据结构优化出更好的遍历方式...不写了....
10 月 31 日
匿名 的圖片
putaoefu 撰寫:
下面是我关于如何找到其中一个起点加油站的想法:


1. 取环上任意一点固定
2. 从这一点开始,顺序计算顺时针方向上后面各点的新位置
3. 新位置满足的条件是: 任意相邻的两点,前一点的油量,恰好够跑完这两点之间的新距离
4. 计算各点新位置和老位置之间的位移,顺时针移动为正,位移最多的点为起点
10 月 31 日

引用通告

此內容的引用通告是:
http://eparg.spaces.live.com/blog/cns!59BFC22C0E7E1A76!367.trak
引述這則內容的部落格