题目大意:
给出一个整数n,找出离n最近且比n大的循环数。
循环数的定义:首先循环数的各位数字互不相同。其次,如果你从最左边的数字开始向右数最左边这个数(如果数到了最右边就回到最左边),你会停止在另一个新的数字(如果停在一个相同的数字上,这个数就不是循环数),重复之前步骤,在经过每个数字一次后回到起点的就是循环数。如果经过每一个数字一次以后没有回到起点, 那么便不是循环数。
思路:
模拟题。首先找出比n大且各位数字互不相同的整数,再判断这个整数是否为循环数。
代码:
/* ID: lujunda1 LANG: C++ PROG: runround */ #include<iostream> #include<stdio.h> using namespace std; int trans(long long n,short num[]) //将n的各位数字存储进num[]中。注意num[]中数字顺序与n相反。 //返回值为n的位数。 { int len=0; while(n) { num[len]=n%10; n/=10; len++; } return len; } bool check(long long n) //检查n是否循环数。 { short num[20]; bool mark[10]; for(int i=0;i<10;i++) mark[i]=false; int len=trans(n,num),temp=len-1,sum=0; //len是n的位数。 //temp用于表示当前数字在num[]中的位置。。 //sum是循环变量。 while(++sum) //通过循环实现判断。 //判断方式模拟题干中对循环数的描述。 { if(mark[num[temp]]&&temp!=len-1) return false; if(mark[num[temp]]&&temp==len-1) return sum==len+1?true:false; mark[num[temp]]=true; int dis=num[temp]%len; temp=temp<dis?len+temp-dis:temp-dis; } } long long search(long long n) //搜索离n最近的没有重复数字的整数。 { long long t=n; long long mark[10]={0}; for(long long i=1;t;i*=10,t/=10) { if(mark[t%10]) return search(n+mark[t%10]); mark[t%10]=i; } return n; } int main() { freopen("runround.in","r",stdin); freopen("runround.out","w",stdout); long long n; scanf("%lld",&n); while(!check(n=search(++n))){} printf("%lld\n",n); }