Codeforces 652F解決レポート

問題の意味

N-アリ各アリ当たり、反時計回りに、リング上のグリッドに向かって向きを格子の数を格子長はMです。相互交流と衝突し2匹のアリの方向がある場合は、t秒後の各アリ位置を尋ねます。

問題の解決策

最初の観測がで見つけることができます

  • 軌道を得アリ衝突は、他の2匹の蟻を通して見ることができます
  • 衝突が各方向を交換します後、各蟻の相対数は変わらないので、つまり、各蟻の「隣人」は変更されません

言い換えれば:

  • 私はtは何の位置を知っている各アリ妨害されずに生成された軌道秒アリを計算することができます
  • また、各アリ比較的一定数いるので、私はちょうどアリのすべての残りの部分の位置を計算するためにt秒後にいくつかのアリの位置を知っています

質問は今、2番目の質問への最初の質問で変換されます。

  • x番目アリのT秒位置が
  • x番目の位置の後にはアリのt秒は番号ではありません

2番目の質問については、限り、我々は配列位置番号サイズのソートを押した後にアリのt秒を見つけるような答えを計算することができます。順序の初期サイズでアリの開始位置番号、位置0の臨界点である、アリシーケンスの後t秒を得る2つのケースを考える(1中間位置Mの位置)とします。

  • すべてのアリは、t秒衝突しない:アリからメートル1から0に行くとき、アリはアリがそうでのみ最初の2番目となり、そしてだろう、最後のアリになります。アリは、0から1メートルを通ってくる場合も同様に、それは最初のアリアリとなるであろう。限り我々アリt秒が夜12時を経て夜12時を通じて何回右から左または左から右に計算されて、その差はt秒アリの順に取得することができ。

  • :t秒は、衝突をアリアリ軌道は、他の側から見ることができるので、アリの衝突がある場合、私たちはただ、上記のように、午後12時で両方向のアリの数を計算するために、衝突の外の状況を無視することができますその場合。左たら、0時あらゆる権利、右の共感が残した蟻時系列上に配置されています。

举个例子,假如一开始蚂蚁编号的排列顺序为[1,3,2],在某一秒2从m点通过了0点到1点,序列变成[2,1,3]。假如2与1发生碰撞,2再次反向通过0点,排列顺序又变回[1,3,2]。看上去好像要判断蚂蚁2从不同方向经过了0点,但是我们完全可以忽略碰撞看成蚂蚁2从左边经过了一次0点和蚂蚁1从右边经过了一次0点,对于复杂的情况也完全适应。

此时我们已知:

  • t秒后那些位置上有蚂蚁
  • t秒后蚂蚁按位置的排序

我们就可以直接一一对应上蚂蚁的位置了

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

おすすめ

転載: www.cnblogs.com/Ace-Monster/p/11723801.html