题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34594
有一个m位n进制的数,它的特性是这个数依次乘以2,3.......m,最后得到的数仍然为这个数的某个排列,例如:
有一个6位十进制数:142857
2 x 142,857 = 285,714
3 x 142,857 = 428,571
4 x 142,857 = 571,428
5 x 142,857 = 714,285
6 x 142,857 = 857,142
那么输入6 10就应该有输出142857(假定这样的数有且仅有一个),如果没有,输出not find
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int m,n,a[10],b[10],p[10],aa[10],ans[10]; bool ak() { int c[10]; for(int i=0;i<m;i++) c[i]=b[i]=a[p[i]]; //生成待检测的数 for(int k=2;k<=m;k++) { for(int i=0;i<m;i++) { c[i+1]+=(c[i]+b[i])/n; //不直接乘以k是因为每次c[i],b[i]才不方便初始到原有状 态 c[i]=(c[i]+b[i])%n; } for(int i=0;i<m;i++) aa[i]=c[i]; sort(aa,aa+m);sort(ans,ans+m); //检验是否是原来的数的某个排列 for(int i=0;i<m;i++) if(aa[i]!=ans[i]) return 0; } return 1; } bool dfs(int cur) { if(cur==m) return ak(); for(int i=cur;i<m;i++) { swap(p[cur],p[i]); if(dfs(cur+1)) return 1; swap(p[cur],p[i]); } return 0; } bool check(int x) { int t=0; for(int i=0;i<m;i++) { t=(t+x)%n; a[i]=t; p[i]=i; ans[i]=t; } return dfs(0); } int main() { while(scanf("%d%d",&m,&n)!=EOF&&m) { int flag=0; for(int i=1;i<n;i++) { if(check(i)) { flag=1; break; } } if(!flag) printf("Not found. "); else { printf("%d",b[m-1]); for(int i=m-2;i>=0;i--) printf(" %d",b[i]); puts(""); } } return 0; }