【问题描述】
YJC 很喜欢玩游戏,今天他决定和朋友们玩密码游戏。
密码游戏的规则是这样的:初始时有两个大小为 m 的数组 a 和 b,分别是 0~m-1 的一
个排列。每一次操作在 0~m-1 之间选一个数 x,求出结果 y=b[a[x]],把 x 和 y 写下来。之
后,a 数组向前循环移动一次,即(a[0],a[1],…,a[m-2],a[m-1])变成(a[1],a[2],…,a[m-1],a[0])。
当 a 数组变回初始状态时,b 数组向前循环移动一次。现在知道所有的 x 和 y,如果 YJC 能
求出任意一组符合条件的 a 和 b 的初值,YJC 就赢了。
YJC 很想赢得游戏,但他太笨了,他想让你帮他算出 a 和 b 的初值。
【输入格式】
第一行包含两个整数 n 和 m,表示操作了多少次和 a、b 数组的大小。
第二行包含 n 个整数,第 i 个数表示第 i 次选出的 x。
第二行包含 n 个整数,第 i 个数表示第 i 次求出的 y。
【输出格式】
第一行包含 m 个整数,表示 a 的初值。
第二行包含 m 个整数,表示 b 的初值。如果有多组答案,输出任意一组即可。
【输入输出样例】
password.in
4 2
0 0 0 0
0 1 1 0
password.out
01
01
【数据说明】
对于 30%的数据,满足 m≤5,n≤1000。
对于 100%的数据,满足 2≤m≤26,m 2 ≤n≤100000,保证数据随机,且存在至少一组 a
和 b。
题解:
emmm由于我比较弱,所以谨献上我30分代码……
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<cmath> #include<queue> #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=100002; int n,m,x[N],y[N]; int c[N],d[N],a[N],b[N]; void move1(){ int s=c[0]; for(int i=0;i<m;i++) c[i]=c[i+1]; c[m-1]=s; } void move2(){ int s=d[0]; for(int i=0;i<m;i++) d[i]=d[i+1]; d[m-1]=s; } bool pd(){ int cnt=0; for(int i=0;i<n;i++){ if( y[i] != d[c[x[i]]] ) return 0; move1(); cnt++; if(cnt==m) { cnt=0; move2(); } } return 1; } void outt(){ for(int i=0;i<m;i++) printf("%d ",a[i]); printf(" "); for(int i=0;i<m;i++) printf("%d ",b[i]); } int flag=0; int main(){ freopen("password.in","r",stdin); freopen("password.out","w",stdout); scanf("%d %d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&x[i]); for(int i=0;i<n;i++) scanf("%d",&y[i]); for(int i=0;i<m;i++) { a[i]=i; b[i]=i; } do{ do{ for(int i=0;i<m;i++) { c[i]=a[i]; d[i]=b[i]; } if(pd()==1) { flag=1; outt(); break;} }while(next_permutation(b,b+m)); if(flag==1) break; }while(next_permutation(a,a+m)); }