逆流invert
#include<bits/stdc++.h> using namespace std; const int N=100005; int n,L,T,a[N],b[N]; int read() { int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') { if(ch=='-') { f=-1; } ch=getchar(); } while (ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } int main() { n=read(); L=read(); T=read(); int s=1; for (int i=1;i<=n;i++) { int x=read(),w=read(); if (w==1) { a[i]=(x+T)%L; if (T>=L-x) { (s-=(T-L+x)/L+1)%=n; } } else { a[i]=((x-T)%L+L)%L; if (T>=x+1) { (s+=(T-x-1)/L+1)%=n; } } } s=(s%n+n-1)%n+1; sort(a+1,a+n+1); for (int i=1;i<=n;i++) { b[(s+i-2)%n+1]=a[i]; } for (int i=1;i<=n;i++) { printf("%d\n",b[i]); } return 0; }
注意审题!@_@ T为时间环长度!不是最大数目!#_#
2.1 n, L, T ≤ 100 考虑如何通过当前时刻的状态求出下一个时刻的状态。对于某一个颜神 i,设他沿着当前方向前进 一个时刻会到达 p,若另一个颜神从 p 以相反的方向前进,那么颜神 i 下一个时刻会回到原来的位置, 并且前进方向与原来相反。否则下一个时刻就会来到位置 p。注意若有另一个颜神在下一个时刻与颜神 i 位于相同的位置,则颜神 i 的前进方向还要改变一次。 暴力模拟上述过程,每次 O(n) 求出一个颜神在下一个时刻的状态。 时间复杂度 O(n 2T)。期望得分:20.
2.2 n, L, T ≤ 2000 延续上述做法,发现可以通过用一个桶记录位于每个状态的颜神数量,就可以优化为每次 O(n+L) 求出下一个时刻所有颜神的状态。 时间复杂度 O((n + L)T)。期望得分:40.
2.3 Wi = 1 由于所有颜神以相同的速度向着相同的方向前进,故不会有相遇的情况发生。因此可以直接 O(1) 求出每个颜神的最终位置。 时间复杂度 O(n)。期望得分:10.
2.4 不会有颜神逆着时间线经过时刻 0,或顺着时间线经过时刻 L 若把颜神看成是无标号的,那么无论颜神相遇后是否改变方向,行走的轨迹都是一样的。若规定颜 神相遇后不改变行走方向,就可以得到 T 个时刻后每个位置的颜神数量。又注意到颜神之间的相对位 置并不会发生改变,所以最终状态中颜神所在位置的下标也仍然保持单调递增。只需要把每个颜神顺 着初始方向行头 T 个时刻后到达的位置排序后输出即可。 时间复杂度 O(n log n)。期望得分:20.
2.5 正解 先求出所有颜神最终所在的位置集合。初始状态坐标最小的颜神编号为 1。在行走过程中,若有一 个颜神从 0 走到 L − 1,那么坐标最小的颜神的编号就会加 1(i%n+1)若有一个颜神从 L − 1 走到 0,坐标最 小的颜神的编号就会减 1(i%n-1)这样就可以得到最终位置的坐标最小的是哪一个颜神了。 时间复杂度 O(n)。期望得分:100