有n只蚂蚁在长度为m个格子的环上,环上的格子以逆时针编号,每只蚂蚁每秒往它面向的方向移动一格。若是有两只蚂蚁相撞则相互调换方向,问t秒后每只蚂蚁的位置。ios
首先经过观察能够发现c++
也就是说:spa
如今的问题就由第一个问题转换成第二个问题:code
对于第二个问题,咱们只要求出t秒后蚂蚁按位置编号大小排序的序列就能够算出答案。假设一开始蚂蚁按初始位置编号的大小顺序排好,位置0(位置1与位置m的中间)是一个临界点,考虑两种状况来求出t秒后蚂蚁的顺序:排序
t秒内全部蚂蚁没有发生碰撞:当有蚂蚁从1通过0走到m时,那么这只蚂蚁就会变成最后一只蚂蚁,第二只蚂蚁会变成第一只,以此类推。同理,当有蚂蚁从m通过0走到1时,这只蚂蚁就会变成第一只蚂蚁。所以咱们只要计算t秒内蚂蚁有多少次从右至左走过0点或从左至右走过0点,求差就能够获得蚂蚁在t秒后的顺序。ci
t秒内有蚂蚁发生碰撞:若是有蚂蚁发生碰撞,由于蚂蚁的轨迹能够当作穿过对方,所以咱们仍是能够忽略掉碰撞的状况去计算蚂蚁从两个方向经过0点的次数,就当成上面那种状况。每从右向左经过0点一次,蚂蚁的排列序列就左移一次,向右同理。it
举个例子,假如一开始蚂蚁编号的排列顺序为[1,3,2],在某一秒2从m点经过了0点到1点,序列变成[2,1,3]。假如2与1发生碰撞,2再次反向经过0点,排列顺序又变回[1,3,2]。看上去好像要判断蚂蚁2从不一样方向通过了0点,可是咱们彻底能够忽略碰撞当作蚂蚁2从左边通过了一次0点和蚂蚁1从右边通过了一次0点,对于复杂的状况也彻底适应。io
此时咱们已知:class
咱们就能够直接一一对应上蚂蚁的位置了sort
#include<bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int i=(a); i<(b); i++) #define per(i, a, b) for(int i=(a-1); i>=(b); i--) typedef long long ll; const int maxn = 300005; const int inf = 0x3f3f3f3f; struct A { ll pos; char f; bool operator<(const A &x) const { return pos < x.pos; } }a[maxn]; int id[maxn], ans[maxn]; int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); ll n, m, t; cin >> n >> m >> t; int offset = 0; rep(i, 0, n) { id[i] = i; cin >> a[i].pos >> a[i].f; a[i].pos--; } //排序获得蚂蚁的初始排列 sort(id, id + n, [&](int x, int y) { return a[x].pos < a[y].pos; }); //计算蚂蚁t秒后的排列,顺便算出t秒后哪些位置出现了蚂蚁 rep(i, 0, n) { if (a[i].f == 'L') { offset = (offset + (a[i].pos - t - m + 1) / m) % n; a[i].pos = ((a[i].pos - t)%m + m) % m; } else { offset = (offset + (a[i].pos + t) / m) % n; a[i].pos = (a[i].pos + t) % m; } } offset = (offset + n) % n; //对位置排序 sort(a, a + n); //此时初始次序为i编号为id[x]的蚂蚁在t秒后变成了次序为(i+offset)%n的蚂蚁 rep(i, 0, n) ans[id[i]] = a[(i + offset)%n].pos + 1; rep(i, 0, n) cout << ans[i] << ' '; return 0; }