决定了要把算法学习提到日程上来,开始学习蓝书。为了注册UVa真是费了好大一番功夫虽然最后也没有注册成功。不过发现了一个特别好的网站https://vjudge.net/,安利一下~
UVa10881 蚂蚁
题目概述:
在一根长为l的木棍上,有n个蚂蚁,给出初始位置和运动方向,然后两只蚂蚁碰头就回头,回头时间不计。按照输入顺序输出t秒后的各个蚂蚁的位置和方向。如果掉下去了就输出“Fell off”。正在转身的蚂蚁输出Turning和位置坐标。
分析:一开始看到这个题,第一想法就是模拟,一秒一秒的模拟。看了书上的想法,感觉真是机智无比。宏观来看,蚂蚁都是1m/s的速度走,碰头转身或者交叉继续走,效果是一样的(方向呢?)。然后按照题目要求,碰头转身,那么蚂蚁的相对位置应该是不变的。但是又要求按照输入顺序输出,而输入顺序不一定是从左到右。所以按照合理的顺序输出也是一个难点。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=10000+5;
struct Ant{
int p;
int direction;
int id;
bool operator < (const Ant &a) const{ //运算符重载,用于sort函数。
return p<a.p;
}
}before[maxn],after[maxn];
const char Dir[][10]={"L","Turning","R"};
int order[maxn];
int main()
{
int i,test,rt;
scanf("%d",&test);
for (rt=1;rt<=test;rt++)
{
int l,t,n,po,d;
int i;
char dir;
scanf("%d%d%d",&l,&t,&n);
for (i=0;i<n;i++)
{
scanf("%d %c",&po,&dir);
if (dir=='L')
d=-1;
else
d=1;
before[i]=(Ant){po,d,i}; //这时候每一个id记录的是输入顺序。
after[i]=(Ant){po+d*t,d,0};
}
sort(before,before+n); //按照位置排序,现在的顺序是从左到右。
for (i=0;i<n;i++)
{
order[before[i].id]=i; //order数组下标是输入顺序,值是位置顺序。
}
sort(after,after+n); //因为t秒后相对位置不变,所以按照后来位置排序,对应的蚂蚁不变。
for (i=0;i<n-1;i++)
{
if (after[i].p==after[i+1].p) //如果t秒时位置相同说明正在转身。
{
after[i].direction=0;
after[i+1].direction=0;
}
}
printf("Case #%d:\n",rt);
for (i=0;i<n;i++)
{
if (after[order[i]].p<0 || after[order[i]].p>l) printf("Fell off\n"); //输出是after[order[i]]的内容,也就是第一个输入的位置顺序
else
{
printf("%d %s\n",after[order[i]].p,Dir[after[order[i]].direction+1]);
}
}
printf("\n");
}
return 0;
}
这个题在输出格式上坑了好多次。。。presentation error.....
嗯,思路就是这样。