有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; }