Loading

【题解】CF1624F Playing Around the Table

哈希表有一种简易的实现方式,求出 \(key = x\bmod P\),如果 \(hash_{key}\) 被占用了,那么就一直向后跳指针直到一个空的位置。

那么对于这题,我们可以用类似的思想,如果一个数归位了,那么就把它存下来,否则让它一直向后滚动直到某次可以存下它。

但是这样会遇到每个人 \(i\) 被还原的时候不同。那么如果 \(i\) 先被还原了,那么下一次滚动必然会破坏已经还原的状态。

换一种思路,我们先把每个人还原成 \(1\sim n\),那么如果一个人被还原了,接下来无论上家给自己什么,自己都可以吐出去相同的。

然后再把每个人还原,具体操作是枚举步长 \(l\),每次把玩家 \(i\) 前面 \(l\) 的人手上的 \(i\) 放在一轮一起还原。

#define N 105
int n, c[N][N], p[N], ans[N * N][N], t;
#define ck(x) (x > n ? (x - n) : x)
int main(){
	read(n);
	rp(i, n)rp(j, n){
		int x; read(x);
		c[i][x] ++;
	}
	while(true){
		rp(i, n){
			p[i] = 0;
			rp(j, n)if(c[i][j] > 1)p[i] = j;
		}
		int w = 0;
		rp(i, n)if(p[i])w = i;
		if(!w)break;
		rp(i, n){
			int x = w == n ? 1 : w + 1;
			if(!p[x])p[x] = p[w];
			w = x;
		}++t;
		rp(i, n)ans[t][i] = p[i], c[i][p[i]]--, c[ck(i + 1)][p[i]]++;
	}
	pre(i, n, 2)rep(j, 1, n - i + 1){
		++t; 
		rep(k, 1, n)ans[t][ck(i + j + k - 2)] = k;
	}
	printf("%d\n", t);
	rp(i, t){rep(j, 1, n)printf("%d ", ans[i][j]); el;}
	return 0;
}
posted @ 2022-03-25 16:14  7KByte  阅读(65)  评论(0编辑  收藏  举报