暴力思路,不断累加当前数,判断是否为循环数:
- 每个数字位均不同
- 数字位不能有(0)
- 在所有数字上均停留一次后,回到出发点(最左边的数字),即每个数字位只能访问一次
bool used[10]; // 标记数字是否已使用
bool vis[10]; // 标记下标是否已访问
int m;
bool isunique(int n)
{
memset(used,0,sizeof used);
while(n)
{
int t=n%10;
if(used[t]) return false;
used[t]=true;
n/=10;
}
return true;
}
bool circle(string s)
{
memset(vis,0,sizeof vis);
for(int i=0,j=0;i<s.size();i++)
{
int k=s[j]-'0';
j=(j+k)%s.size();
if(vis[j]) return false;
vis[j]=true;
}
return true;
}
int main()
{
cin>>m;
while(true)
{
m++;
if(isunique(m) && circle(to_string(m)))
{
cout<<m<<endl;
break;
}
}
//system("pause");
return 0;
}
考虑到数字位各不相同的数在(2^{32})内只有(9!=362880)个,于是按从小到大顺序生成数字位各不相同的数,判断是否大于(m)且为循环数,第一个满足条件的数即为大于(m)的第一个循环数。
bool used[10]; // 标记数字是否已使用
bool vis[10]; // 标记位置是否已访问
int m;
bool circle(string s)
{
memset(vis,0,sizeof vis);
for(int i=0,j=0;i<s.size();i++)
{
int k=s[j]-'0';
j=(j+k)%s.size();
if(vis[j]) return false;
vis[j]=true;
}
return true;
}
bool dfs(int u,int n,string path)
{
if(u == n)
{
if(stoi(path) > m && circle(path))
{
cout<<path<<endl;
return true;
}
return false;
}
for(int i=1;i<=9;i++)
if(!used[i])
{
used[i]=true;
if(dfs(u+1,n,path+char('0'+i))) return true;
used[i]=false;
}
return false;
}
int main()
{
cin>>m;
int len=to_string(m).size();
while(!dfs(0,len,"")) len++;
//system("pause");
return 0;
}