第一题:圆环
一个圆环上有n个位置,这n个位置按顺时针依次标号为1, 2, …, n。初始时圆环的每个位置上都有一个1至n之间的整数,且每个整数只出现一次。
任何时刻,你可以将圆环上的数全部逆时针旋转一个位置,即第i个位置上的数变为原来第i + 1个位置上的数,第n个位置上的数变为原来第1个位置上的数。也可以将圆环上的数全部顺时针旋转一个位置,即第i个位置上的数变为原来第i – 1个位置上的数,第1个位置上的数变为原来第n个位置上的数。另有一个装置,可以交换圆环上第a个位置和第b个位置上的数。
下图给出了三种操作的示例,圆环上有6个位置,初始数字分别为1, 2, 4, 3, 5, 6,能交换第2个和第3个位置上的数。经过一次逆时针旋转后变为2, 4, 3, 5, 6, 1,交换后变为2, 3, 4, 5, 6, 1,再经过一次顺时针旋转后变为1, 2, 3, 4, 5, 6。

请问通过旋转和交换,能否使得第i个位置上的数正好是i。
输入描述
输入包含多组数据。
每组数据的第一行包含一个整数n,表示圆环上的数字个数。
第二行包含两个整数a, b(1 ≤ a < b ≤ n),表示可以交换圆环上第a个位置和第b个位置上的数。
接下来n行描述圆环上每个位置的初始值,其中第i行包含一个整数ai,表示初始时刻第i个位置上的数。
最后一组数据之后的一行为一个0,表示输入结束。
输出描述
对于每个测试用例,输出一行,如果能满足要求,这行中应只包含一个单词Yes,如果不能满足要求,这行中应只包含一个单词No。
样例输入
6
2 3
1
2
4
3
5
6
4
1 3
1
2
4
3
0
样例输出
Yes
No
提示
对于100%的数据,1 ≤ n ≤ 1,000。
思路:
可以看出a,b的用处就是他们的差
由于可以顺时针逆时针旋转
所以可以看作任意相邻为|a - b| + 1的两个元素可以交换
再推广
记tmp = |a - b| + 1
那么在下标列 f1,f2, f3, f4 。。。。
假设fi = f(i - 1) + tmp
那么可以知道 在fi上的位置的数的任意两个可以交换 记此为同集合
所以 当n % tmp != 0
可以发现整个数列都可以互换,所以直接YES
不然对于每一个集合检查是否可以转换一个序列,使得A[f[i]] - A[f[i - 1]] = tmp
不能就为NO,能则YES
具体可以开hash检查
时间n^2
代码略
浙公网安备 33010602011771号