BNU 26579 Andrew the Ant 【螞蟻】

鏈接:




Andrew the Ant

4000ms
65536KB
64-bit integer IO format: %lld      Java class name: Main
Font Size:  
Type:  

 

Andrew the Ant is fascinated by the behavior of his friends. Thousands of them are marching their paths on and on. They can build highly organized ant-hills. Sometimes, however, they act a little bit stupidly.

Recently, Andrew watched his fellow ants marching on top of a long piece of wood. He noticed their behavioral pattern is very simple: Each ant walks slowly forward with a constant speed of 1 cm per second. Whenever it meets another ant, both of them only touch with their antennae and immediately turn around and walk the opposite direction. If an ant comes to the end of the wood, it falls down and does not affect other ants anymore.

 

The picture above shows an example of moving ants in time 0 s. In one second, the ants E and A meet at position 2 and change their directions. The ant A then meets B in the next 1.5 seconds. At the same time (2.5 seconds after the start), the ants C and D will meet too. All four of them change their directions. In the next 0.5 second (time 3 s), the first ant (E) falls down off the left end, etc.

Your task is to simulate the movement of ants. For simplicity, suppose that the ants have zero size (although the picture could suggest something else).

 

 

Input

 

The input consists of several scenarios. Each scenario starts with a line containing two integer numbers L and A, separated by a space. L is the length of the wood in cms (1 ≤ L ≤ 99 999), and A is the number of ants at the beginning of the simulation (1 ≤ A ≤ L + 1).

Then there are A lines, each containing a positive integer Xi, one space, and an uppercase letter. The number (0 ≤ X≤ L) specifies the position of the i-th ant and the letter its initial direction: either “L” for left (towards zero) or “R” for right. No two ants will start at the same position.

Output

 

For each scenario, you should print a single line containing the text “The last ant will fall down in T seconds - started at P.”, where T is the exact time when the last ant (or two) reaches the end of the wood, and P is the position where that particular ant has originally started in time 0. If two last ants fall down at the same time, print “started at P and Q”, indicating both of their positions, P <Q.

Sample Input

90000 1
0 R
10 1
0 L
14 5
3 L
6 L
13 L
8 R
1 R

Sample Output

The last ant will fall down in 90000 seconds - started at 0.
The last ant will fall down in 0 seconds - started at 0.
The last ant will fall down in 13 seconds - started at 6 and 8.

Hint

 

(The last sample input scenario corresponds to the picture.)

Source




參考資料:lrj 《算法競賽入門經典——訓練指南》


P9-P11:例題 5 螞蟻 【UVa 10881 Piotr's Ants】

再次膜拜神書 Orz



題意:


一根長度爲 L 釐米的木棍上有 n 只螞蟻,每隻螞蟻要麼朝左爬,要麼朝右爬,速度爲 1釐米/秒。
當兩隻螞蟻相撞時,二者同時掉頭(掉頭時間忽略不計)。
給出每隻螞蟻的初始位置和朝向,計算最後掉下去的螞蟻所用的時間和該螞蟻的初始位置。

如果最後一刻有兩隻螞蟻掉下去,那麼按照它們的初始位置從左到右輸出。【沒注意這一點WA。。。】

注意:由螞蟻相遇就馬上掉頭可以知道,最後一刻至少有一隻螞蟻掉下去,而最多只可能有兩隻螞蟻【一頭一尾】。

輸入:第一行 L,N 
            L 代表木棍長度(1 ≤ L ≤ 99 999)
            N 代表螞蟻個數(1 ≤ N ≤ L + 1).

與 Uva 10881 的比較
Uva 中是給出每隻螞蟻的初始位置和朝向, 計算 T 秒之後每隻螞蟻的位置。

思路:

其實是看的書上的關於 Uva 10081 的,自己就算能想到,也弄不了這麼細緻的。

如果不區分螞蟻的編號,那麼螞蟻相遇後的 “掉頭” 不就可以看成是“對穿而過”

比如,有 3 只螞蟻,螞蟻 1 = (1,R),  螞蟻 2 = (3, L),  螞蟻 3 = (4, L)
則 2 s 後,3 只螞蟻的狀態分別爲 (3, R), (1, L) 和 (2, L)。
注意:這裏只是確定了各個螞蟻的位置,但是卻忽略了,目標狀態中的螞蟻和初始狀態中的螞蟻的對應情況,也就是說弄混了“誰是誰”。

但是注意到:相撞就掉頭,所以螞蟻的相對順序是保持不變的。

所以,只要把目標狀態中的螞蟻位置從小到大排序,則從左到右的每個位置對應於初始狀態下從左到右的每隻螞蟻。
注意:原題中螞蟻不一定按照從左到右的順序輸入
            所以還需要預處理計算輸入中的第 i 只螞蟻的序號 order[i].


與 Uva 10881 的比較和轉換

如果是 Uva 根據給你的時間 T 判斷,T 時各個螞蟻的狀態。
注意到:本題是算最後落下的螞蟻的信息。
               那麼我們根據每個螞蟻的初始位置,很容易計算出最後一隻螞蟻的落地時間 T 稍微改下 Uva 的代碼即可。


注意

由題目樣例知道:初始在邊緣的而且往木棍外面走的螞蟻最終下落時間記爲 0

                            所以計算的時間 T 就按照最後一隻到了邊緣的螞蟻用的時間 T 計算, 而不是 T-1。


code:

#include<stdio.h>
#include<algorithm>
using namespace std;

const int maxn =  99999+10;

struct Ant{
	int id; //輸入順序 
	int p; //位置 
	int d; //朝向。-1:左; 0:轉身中;1:右 
	bool operator < (const Ant& a) const { //按照 p 從左到右排序 
		return p < a.p;
	}
}before[maxn], after[maxn]; //初始狀態和最終狀態 

int order[maxn]; //輸入的第 i 只螞蟻是最終狀態中的左數第 order[i] 只螞蟻 

struct Node{ //記錄初始輸入狀態 
	int p;
	int d;
}node[maxn];

int id[2];//記錄最後下落的螞蟻的編號 

int main()
{
	int L,n; //木棍長度和螞蟻個數 
	while(scanf("%d%d", &L,&n) != EOF)
	{
		int T = 0;
		
		for(int i = 0; i < n; i++)
		{
			int p, d;
			char c;
			scanf("%d %c", &p, &c);//輸入因爲第二個是字符注意添加空格
			d = (c == 'L' ? -1 : 1);
			
			int t;
			if(d == -1) t = p;
			if(d == 1) t = L-p;
			
			T = max(T, t); //最後一隻螞蟻下落時間【正好到邊緣】 
			
			node[i] = (Node) {p, d};
		}
		
		for(int i = 0; i < n; i ++)
		{
			int p = node[i].p;
			int d = node[i].d;
			
			before[i] = (Ant) {i, p, d}; //初始狀態 
			after[i] = (Ant){0, p+T*d, d}; //最終狀態, id 未知, 可以忽略 d 
		}
		
		//計算 order 數組 
		sort(before, before+n); //按照螞蟻的初始位置排序, 並未改變其 id 
		for(int i = 0; i < n; i++)
			order[before[i].id] = i; //輸入的第 i 只螞蟻是最終狀態中的左數第 order[i] 只螞蟻 
		
		//計算最終狀態:按照螞蟻位置從左到右排序	
		sort(after, after+n);
		
		int index = 0; //記錄最後一刻下落的螞蟻個數 
		for(int i = 0; i < n; i++)
		{
			int a = order[i];
			if(after[a].p == 0 || after[a].p == L) id[index++] = i; //正好到邊緣 
		}
		if(index == 1) //如果只有一隻螞蟻 
		{
			int p1 = node[id[0]].p;
			printf("The last ant will fall down in %d seconds - started at %d.\n", T, p1);
		}
		
		else if(index == 2) //如果有兩隻螞蟻,按照初始位置從左到右輸出 
		{
			int p1 = min(node[id[0]].p, node[id[1]].p);
			int p2 = max(node[id[0]].p, node[id[1]].p);
			printf("The last ant will fall down in %d seconds - started at %d and %d.\n", T, p1, p2);
		}
	}
	return 0;
}



總結:


  第三場組隊賽了,還是太過於浮躁,第一個 AC 的題是一道簡單的 DP 一年前就做過的,很快的明確了思路,開始敲,這時Orc 在看螞蟻的這一題。結果沒有敲完就把編譯器給弄壞了,然後把代碼交個 Orc 各種改,我就各種安裝編譯器,最終 cb 還是弄壞了,只好裝上很久以前用的 cfree 各種不習慣,還好這個時候 Orc 已經把 DP 改出來了,由於 int64 和 long long 問題 WA 了一次,馬上AC了。已經過了一個小時了。排第6。。。各種悲催!

   然後 Orc 對我說 D 題是計算幾何很多人過了,我馬上去看 D 他繼續看螞蟻的這題。我看了下發現 D 不是計算幾何而是簡單的 BFS 才一百個點,但是沒有看清楚題目中的英文,暫時猜測了下方向和騎士周遊世界是一樣的,然後我開始以這個思路敲,同時讓Orc 也看看這題,方向是不是和我猜測的一樣。然後很快就過了樣例!問了下 Orc 決定交。慘淡的 TLE 。。。這可是 100 個點的 BFS 啊。。。。。。。然後讓Orc檢查,然後我發現是初始標記起點入隊寫錯了,改了還是 TLE (此時貢獻了兩次TLE了)然後就是各種檢查,各種數據測試,都沒問題,最終快到 2 點的時候 Orc 發現我在輸入的時候掉了 != EOF敲打 檢查了那麼久都沒有發現問題啊!!!

   看了下排行榜這時兩題第三吧,要是不白交兩次 TLE 就應該是第二了。然後最後一題分巧克力的看有人過了,Orc猜測應該比較簡單,但是我實在是看不懂題目就沒有管了,然後看了下 F 有人過了,看了輸入和輸出發現和斐波拉契生兔子的有點像,再仔細看了下題目背景,發現是一水題,很快 AC 了,這時 2:49 了。3題排第三吧,學妹那支隊伍這幾次都表現的比較好,一直在我們前面,不是第一就是第二。然後又回來看最後一題,最終是 Orc 看懂了題目,然後我各種 YY 還是沒有枚舉分析完,比賽完了,Orc看了下題解說是斐波拉契。。。然後我看了下 B 的字符串 WA 的人很多,自己也沒法下手,然後又去看了下 A 就是這道螞蟻的題目,也發現了轉換問題。。。正式開始寫的時候只有半個小時了,很快寫完了,但是計算時間的時候我是輸入完了之後在計算 T 的,然後寫 d  的時候不是算的每一個螞蟻的,寫錯了,算成了最後一隻螞蟻的,樣例和自己的數據都無法查出錯誤。。。。然後就這樣 WA 到了比賽完。最後一題很多人做我們又沒有寫出來,最終 3 題排第 5 弱爆了,被兩隻老隊伍踩外加兩支新隊伍踩。。。

    難題做不出,簡單題讀題速度不夠快,寫簡單題目的時候心態又不夠平和,各種小錯誤,導致很久才能 AC 。

    lrbj 回家了,每次還好有 Orc 來改錯,然後基本上都是他先 AC 題目,避免了暴 0 的情況,比的心裏也有點底吧。比賽基本上都看不到計算幾何的題目,等 lrbj 來了三人合作情況應該會好一點,至少罰時什麼的不會這麼多了吧。看英文題目的速度會快一點,然後基礎題目 AC 的速度應該也會快點。現在才越來越體會到合作的重要性。不過我們兩個雖然每次敲代碼的時候只用了一臺電腦,但是卻用了兩臺電腦看題目,也是自己單獨敲的,這種習慣很不好,正式比賽一臺電腦肯定是不會適應的了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章