Problem:
http://ace.delos.com/usacoprob2?a=GDaP3qeGiYp&S=runround
Answer:
/*
ID:iby071
TASK:runround
LANG:C++
*/
#include<iostream>
#include<fstream>
using namespace std;
bool check(unsigned long int n)
{ int digit=0,k;
int num[20];
bool visited[20];
bool makeup[10];
unsigned long int tmp=n;
for(int i=0;i<10;++i)
makeup[i]=false;
while(tmp!=0) //这里生成的num[]是逆序的
{ num[digit]=tmp%10;
if(num[digit]==0 || makeup[num[digit]]) return false; //循环数组成中不能有0,不能有重复数字
makeup[num[digit]]=true;
tmp/=10;
++digit;
}
for(int i=0;i<digit;++i)
visited[i]=false;
k=digit-1;
visited[digit-1]=true;
for(int i=0;i<digit;++i)
{ k=((k-num[k]%digit)+digit)%digit; //mod原因:从下标k向左num[k]次会越界;第一次mod:num[k]>=digit;第二次mod:num[k]>k
if(visited[k]) break;
visited[k]=true;
}
if(k!=digit-1) return false; //没有回到初始位置,不是循环数
for(int i=0;i<digit;++i)
if(!visited[i]) return false; //在digit次访问中,有些位没被访问,不是循环数
return true;
}
int main()
{ ifstream fin("runround.in");
ofstream fout("runround.out");
unsigned long int m,n;
fin>>m;
for(n=m+1; ;++n)
if(check(n)) {fout<<n<<endl;break;}
return 0;
}