90 循环数
90 循环数
作者:
问题描述 :
循环数是那些不包括0这个数字的没有重复数字的整数 (比如说, 81362) 并且同时具有一个有趣的性质, 就像这个例子:
如果你从最左边的数字( 记为n,在这个例子中是8) 开始往右边数,一直数n个数字(如果已经到了最右边则回到最左边),你会停在另一个不同的数字上。如果停在一个相同的数字上,这个数就不是循环数。
就像: 8 1 3 6 2 从最左边接下去数8个数字: 1 3 6 2 8 1 3 6 所以下一个数字是6. 重复这样做 (这次从'6'开始数6个数字) 并且你会停止在一个新的数字上: 2 8 1 3 6 2, 也就是2. 再这样做 (这次数两个): 8 1。 再一次 (这次数一个): 3。 又一次: 6 2 8, 这时你回到了起点。
此时,我们数到的数字依次是:8 6 2 1 3,即每一个数字都被数了1次,并且回到了起点。
如果你将每一个数字都数了1次以后没有回到起点, 你的数字不是一个循环数。
给你一个数字 M (在1到9位之间), 找出第一个比 M大的循环数(输入的M保证这个循环数能保存在4位的有符号整数中)。
输入说明 :
仅仅一行, 包括M
输出说明 :
仅仅一行,包括第一个比M大的循环数。
输入范例 :
111110
输出范例 :
134259
解题思路:这道题目一开始没什么思路,完了半个下午回来后又看看题目,觉得要采用DFS构成子集来枚举数字,并判断是否是循环数。
而如何判断循环数呢?脑子的想法是跟着题目的意思模拟一遍,如果是循环数OK;不是的话继续枚举数字。其中DFS是从9个数中任意选出
n个数字进行全排列
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #include <string.h> 5 #include <ctype.h> 6 7 #define maxn 20 8 9 int rec[maxn]={0,1,2,3,4,5,6,7,8,9}; 10 int hashTable[maxn]={0}; 11 int hash[maxn]={0}; 12 int ans[9]={0}; 13 14 int min,m,n,x = 999999999; 15 void DFS(int index,int a[]); 16 int isLoop(int a[],int len); 17 int main(){ 18 19 scanf("%d",&m); 20 int num = m+1; 21 n = 0;//n位数 22 while(num){ 23 n++; 24 num = num/10; 25 } 26 27 min = x; 28 for(;n<10;n++){ 29 DFS(0,ans); 30 if(min!=x){//找到了,不必深度搜索了 31 break; 32 } 33 } 34 printf("%d\n",min); 35 return 0; 36 } 37 38 void DFS(int index,int a[]){ 39 if(index == n){ 40 int num = isLoop(a,n); 41 if(num>0){ 42 if(num<min){ 43 min = num; 44 } 45 } 46 return ; 47 } 48 if(index > n ){ 49 return ; 50 } 51 int i; 52 for(i=1;i<10;i++){ 53 if(hashTable[i]==0){ 54 a[index] = rec[i]; 55 hashTable[i] = 1; 56 DFS(index+1,a); 57 hashTable[i] = 0; 58 } 59 } 60 } 61 62 int isLoop(int a[],int len){ 63 int i,num; 64 i = num = 0; 65 for(i=0;i<n;i++){ 66 num = num*10+a[i]; 67 } 68 69 if(num<=m){ 70 return 0; 71 } 72 int step = a[0]; 73 int sum = 0; 74 int flag = 0;//默认没有成功 75 while(1){ 76 i = (i+step)%len; 77 if(hash[a[i]]==0){//没有被选择到过 78 sum++; 79 step = a[i]; 80 hash[a[i]] = 1; 81 if(i==0){ 82 if(sum==len){ 83 flag = 1; 84 break; 85 }else{ 86 flag = 0; 87 break; 88 } 89 } 90 }else{ 91 flag = 0; 92 break; 93 } 94 } 95 memset(hash,0,10*sizeof(int));//标记数字复位 96 if(flag == 0){ 97 return 0; 98 }else{ 99 return num; 100 } 101 }