【gdgzezoi】Problem A: 圆上的蚂蚁 Ants on circle

Description

L个点围成一个圆. 我们选定任意一个点作为原点, 则每个点的坐标为从原点顺时针走到这个点的距离. 圆上有N只蚂蚁, 分别被编号为1到N. 开始时, 第i只蚂蚁在坐标为Xi的点上. 这N只蚂蚁同时开始移动. 对于每一只蚂蚁i, 给定其初始方向Wi: 假如i开始时是顺时针走的, 则Wi的值为1; 否则为2. 每只蚂蚁的速度均为1. 当某个时刻两只蚂蚁相遇时, 它们都分别都掉头往反方向走.

对于每一只蚂蚁, 请你求出其开始移动T秒后的位置.

Input

输入格式如下:

N L T
X1 W1
X2 W2
:
XN WN

Output

输出N行, 第i为T秒后第i只蚂蚁所在的坐标.

每个坐标都在[0,L−1]之间.

Sample Input

sample input 1:
3 8 3
0 1
3 2
6 1

sample input 2:
4 20 9
7 2
9 1
12 1
18 1

Sample Output

sample output 1:
1
3
0

sample output 2:
7
18
18
1

HINT

样例 1:1.5秒后, 第1和第2只蚂蚁在坐标1.5处相遇; 一秒后, 1和3在0.5处相遇; 0.5秒后, 也就是开始移动3秒后, 三只蚂蚁分别位于坐标1, 3和0.

所有输入均为整数
1≤N≤105
1≤L≤109
1≤T≤109
0≤X1<X2<⋯<XN≤L−1
1≤Wi≤2

思路

容易算出如果两只蚂蚁相撞之后方向不变继续行走的话,最终每只蚂蚁的位置在哪。我们只需要知道相撞后转向的情况下,每只蚂蚁最终位于不转向情况下哪只蚂蚁的位置。这个直接对每只蚂蚁二分,看他总共会转多少次向,然后就能得到他实际的位置啦。

代码

#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for(int i = (a), i##end = (b); i <= i##end; ++ i)
#define CLR(i, a) memset(i, a, sizeof(i))
#define REPD(i, a, b) for(int i = (a), i##end = (b); i >= i##end; -- i)
#define REPG(i, x) for(int i = head[x], v; i; i = edge[i].next)
#define LOG(x) cerr << #x << ":" << x << endl
#define DBG(...) fprintf(stderr, __VA_ARGS__)
#define OK DBG("Passing [%s] in LINE %d...\n", __FUNCTION__, __LINE__)
typedef long long LL;
typedef double DB;
#define pc putchar
#define gc getchar
#define endl '\n'
inline LL rd() {    
    char ch = gc(); LL ret = 0, sgn = 1;
    while(ch < '0' || ch >'9') {
        if(ch == '-') sgn = -1;
        ch = gc();
    }
    while(ch >= '0' && ch <= '9')
        ret = ret * 10 + ch - '0', ch = gc();
    return ret * sgn;
}
inline void out(LL x) {
    static int buf[50], btp;
    if(x < 0) x = -x, pc('-');
    if(!x) pc('0');
    else {
        btp = 0;
        for(; x; x /= 10) buf[++ btp] = x % 10;
        while(btp) pc('0' + buf[btp --]);
    }
}
  
const int N = 1e6 + 5;
  
LL n, MOD, t, a[N], rk;
  
int main()
{
    scanf("%d%d%d",&n,&MOD,&t); 
    REP(i, 1, n) {
        a[i] = rd();
        int op = rd();
        if(op - 1) {
            a[i] -= t;
            if(a[i] % MOD < 0) -- rk;
            rk += a[i] / MOD;
        }
        else {
            a[i] += t;
            rk += a[i] / MOD;
        }
    }
    rk = (rk % n + n) % n;
    REP(i, 1, n) a[i] = (a[i] % MOD + MOD) % MOD;
    sort(a + 1, a + n + 1);
    // for (int i=1; i<=n; i++) printf("%d\n",a[i]);
    REP(i, rk + 1, n) out(a[i]), pc(endl);
    REP(i, 1, rk) out(a[i]), pc(endl);
    return 0;
}

发布了703 篇原创文章 · 获赞 392 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/Eric1561759334/article/details/100687381
今日推荐