UVA 10881 思维

UVA 10881
题目链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=20&problem=1822&mosmsg=Submission+received+with+ID+16494760
题意:
n只蚂蚁在长度为L的轴上运动,超出边界会掉下去。,速度为1,碰撞时交换方向。
问T秒后蚂蚁位置和状态。
位置为0-L的值或者Fell off。在位置0-L的前提下,两只蚂蚁处于同一位置,方向输出Turning,否则输出L或者R。
思路:
大白书1.1例题5,不会做的单独拿出来写。
传说中的脑洞题。
先写了一发模拟,就是一秒一秒走(因为存在走到一半返回的情况,所以长度和时间均扩展成原来两倍的做法),妥妥TLE。
然后看题解,题解说因为速度相同,蚂蚁碰撞可以看成他们交换了运动方向。所以可以看成不碰撞的情况下求出所有的终点位置,然后每个位置依次为初始的蚂蚁相对顺序123.
源码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
#define LL long long
const int MAXN = 10000 + 5;
int p[MAXN], d[MAXN];
struct Ant
{
    LL p, d;
    int mark;
    int turn;
}ant[MAXN];
struct Tmp
{
    LL p, d;
}temp[MAXN];
char op[MAXN];
bool cmp1(Ant u, Ant v){return u.p < v.p;}
bool cmp2(Ant u, Ant v){return u.mark < v.mark;}
bool cmp3(Tmp u, Tmp v){return u.p < v.p;}
int main()
{
    int T;
    scanf("%d", &T);
    for(int cas = 1 ; cas <= T ; cas++){
        LL len, cnt;
        int n;
        scanf("%lld%lld%d", &len, &cnt, &n);
        for(int i = 1 ; i <= n ; i++){
            scanf("%lld%s", &ant[i].p, op);
            if(op[0] == 'L')    ant[i].d = -1;
            else    ant[i].d = 1;
            ant[i].mark = i;
        }
        sort(ant + 1, ant + n + 1, cmp1);
        for(int i = 1 ; i <= n ; i++){
            temp[i].p = ant[i].p + ant[i].d * cnt;
            temp[i].d = ant[i].d;
        }
        sort(temp + 1, temp + 1 + n, cmp3);
        for(int i = 1 ; i <= n ; i++){
            ant[i].p = temp[i].p;
            ant[i].d = temp[i].d;
        }
        for(int i = 1 ; i <= n ; i++){
            if(i > 1 && ant[i].p == ant[i - 1].p)   ant[i].turn = 1;
            else if(i < n && ant[i].p == ant[i + 1].p)   ant[i].turn = 1;
            else ant[i].turn = 0;
        }
        sort(ant + 1, ant + 1 + n, cmp2);
        printf("Case #%d:\n", cas);
        for(int i = 1 ; i <= n ; i++){
            if(ant[i].p < 0 || ant[i].p > len)  printf("Fell off\n");
            else{
                printf("%lld ", ant[i].p);
                if(ant[i].turn == 1)    printf("Turning\n");
                else if(ant[i].d == -1) printf("L\n");
                else    printf("R\n");
            }
        }
        printf("\n");
    }
    return 0;
}

你可能感兴趣的:(UVA 10881 思维)