uva 10881 - Piotr's Ants

点击打开链接uva 10881

思路:模拟
分析:
1 如果把蚂蚁看成是没有区别的点,那么只需计算出每只蚂蚁在t秒之后的位置即可。比如有三只蚂蚁,蚂蚁1 = (1,L),蚂蚁2 = (3 , L) , 蚂蚁3 = (4,L),则两秒钟之后,3只蚂蚁的位置分别为(3 , R) , (1 , L) , (2 , L)。
2 虽然从整体上讲,“掉头”等价于“对传而过”,但对于每只蚂蚁而言并不是这样。蚂蚁1的初始状态为(1 ,R),因此一定有一只蚂蚁在两秒种之后处于(3 , R)的状态,但这样的的蚂蚁不一定是蚂蚁1.换句话说,我们需要搞清楚目标状态中“谁是谁”。
3 所有蚂蚁的相对的位置是保持不变的,因此把所有目标位置从小到大排序,则从左到右的每个位置对应与初始状态下从左到右的每只蚂蚁。由于原题中蚂蚁不一定是按照从左到右的顺序输入,因此我们预处理计算出输入中第i只蚂蚁的序号order[]

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 100010;
struct Ant{
    int id;
    int p;
    int d;
    bool operator<(const Ant& a)const{
        return p < a.p;
    }
};
Ant before[MAXN] , after[MAXN];
char dir[3][10] = {"L","Turning","R"};
int order[MAXN];

int main(){
    int T, Case = 1;
    int l , t , n; 
    scanf("%d" , &T);
    while(T--){
        scanf("%d%d%d" , &l , &t , &n);
        for(int i = 0 ; i < n ; i++){
           int p , d;
           char c;
           scanf("%d %c" , &p , &c);
           d = c == 'L' ? -1 : 1;
           before[i] = (Ant){i , p , d};//初始化
           after[i] = (Ant){0 , p+t*d , d};//这里的id是未知的
        }
        sort(before , before+n);
        for(int i = 0 ; i < n ; i++)
            order[before[i].id] = i;//输入的第i只蚂蚁是after中左数第after[order[i]]只蚂蚁
        sort(after , after+n);
        for(int i = 0 ; i < n-1 ; i++){
            if(after[i].p == after[i+1].p)
               after[i].d = after[i+1].d = 0;//说明正在碰撞
        }
        //输出结果
        printf("Case #%d:\n" , Case++);
        for(int i = 0 ; i < n ; i++){
            int a = order[i];//从第一个蚂蚁到最后一个蚂蚁
            if(after[a].p < 0 || after[a].p > l)//出界
               printf("Fell off\n");
            else
               printf("%d %s\n" , after[a].p , dir[after[a].d+1]);
        }
        printf("\n");
    }
    return 0;
}



你可能感兴趣的:(uva 10881 - Piotr's Ants)