链接:
Andrew the Ant
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 ≤ Xi ≤ 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 《算法竞赛入门经典——训练指南》
题意:
思路:
注意:
由题目样例知道:初始在边缘的而且往木棍外面走的蚂蚁最终下落时间记为 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 的速度应该也会快点。现在才越来越体会到合作的重要性。不过我们两个虽然每次敲代码的时候只用了一台电脑,但是却用了两台电脑看题目,也是自己单独敲的,这种习惯很不好,正式比赛一台电脑肯定是不会适应的了。