您的位置:首页 > 其它

NYOJ-6174问题-57

2013-07-14 16:11 369 查看
/*6174问题
时间限制:1000 ms  |  内存限制:65535 KB
难度:2
描述
假设你有一个各位数字互不相同的四位数,把所有的数字从大到小排序后得到a,从小到大后得到b,然后用a-b替换原来这个数,并且继续操作。例如,从1234出发,依次可以得到4321-1234=3087、8730-378=8352、8532-2358=6174,又回到了它自己!现在要你写一个程序来判断一个四位数经过多少次这样的操作能出现循环,并且求出操作的次数

比如输入1234执行顺序是1234->3087->8352->6174->6174,输出是4

输入
第一行输入n,代表有n组测试数据。
接下来n行每行都写一个各位数字互不相同的四位数
输出
经过多少次上面描述的操作才能出现循环
样例输入
1
1234样例输出
4来源
[张洁烽]原创
上传者
张洁烽

*/
/*1955年,卡普耶卡(D.R.Kaprekar)研究了对四位数的一种变换:任给出四位数k0,
用它的四个数字由大到小重新排列成一个四位数m,再减去它的反序数rev(m),
得出数k1=m-rev(m),然后,继续对k1重复上述变换,得数k2.如此进行下去,卡普耶卡发现,
无论k0是多大的四位数,只要四个数字不全相同,最多进行7次上述变换,就会出现四位数6174
容易证明,对于任何自然数n>=2,连续做K变换必定要形成循环.这是因为由n个数字组成的数
只有有限个的缘故.但是对于n>=5,循环的个数以及循环的长度(指每个循环中所包含数的个数)
尚不清楚*/

#include<stdio.h>//自己的代码
#include<string.h>//6174问题
void  f(char a[],char d[]){
int  b,i,j;//函数功能:传一个字符串类型的数char a[],将char b[]
char c[10];//变为其最大数和最小的差值,即:a[]=3241,经过f(a,b)后,b[]=4321-1234=3087。。。
strcpy(c,a);
for(i=0;i<4;i++)//冒泡排序
for(j=i+1;j<4;j++)//必须先从大到小否则像3805这样的数就会出错
 if(c[i]<c[j]){//先求出最大
 b=c[j];
c[j]=c[i];
 c[i]=b;
 }strcpy(d,c);
 for(i=3,j=0;i>=0;i--)
c[i]=d[j++];
 
for(i=3;i>=0;i--){//最大减最小
if(d[i]-c[i]<0){
--d[i-1];
d[i]=d[i]+10-c[i]+'0';
}
else if(d[i]==c[i]) d[i]='0';
else      d[i]=d[i]-c[i]+'0';
}
}
int main (){
  int n,count;
 char m[10],p[10];
 scanf("%d",&n);
  while(n--){
     count=1;
scanf("%s",m);
        f(m,p);
      while(strcmp(m,p)){
             strcpy(m,p);
           c ount++;
            f(m,p);
}
printf("%d\n",count);
  }
return 0;
}
 
//他人代码,借鉴
01.
  
 
02.
#include<stdio.h>   

03.
int

get_next(
int
x){  

04.
    
char

s[10];  

05.
    
int

a,b,i,j,n;  

06.
    
n=
sprintf
(s,
"%d"
,x);
//把整型数转换为字符型。返回字符串长度。   

07.
    
for
(i=0;i<n;i++)
//冒泡法排序。   

08.
        
for
(j=i+1;j<n;j++)  

09.
            
if
(s[i]>s[j]){  

10.
                
char

t=s[i];  

11.
                
s[i]=s[j];  

12.
                
s[j]=t;  

13.
            
}  

14.
    
sscanf
(s,
"%d"
,&b);
//把字符型转换为整型,并赋值给b   

15.
    
for
(i=0;i<n/2;i++){
//
翻转字符串。   

16.
        
char

t=s[i];  

17.
        
s[i]=s[n-i-1];  

18.
        
s[n-i-1]=t;  

19.
    
}  

20.
    
sscanf
(s,
"%d"
,&a);
//把字符型的最大数赋值给a   

21.
    
return

a-b;  

22.
}  

23.
int

num[2000],count;  

24.
int

main(){  

25.
    
int

m,found;  

26.
    
scanf
(
"%d"
,&m);  

27.
    
while
(m--){  

28.
        
count=1;  

29.
        
scanf
(
"%d"
,&num[0]);  

30.
            
for
(;;){  

31.
        
num[count]=get_next(num[count-1]);  

32.
        
found=0;  

33.
        
for
(
int

i=0;i<count;i++)  

34.
            
if
(num[count]==num[i]){  

35.
                
found=1;  

36.
                
break
;  

37.
            
}  

38.
            
if
(found)  

39.
                
break
;  

40.
            
count++;  

41.
           
 
42.
            
}  

43.
            
printf
(
"%d\n"
,count);  

44.
       
 
45.
    
}  

46.
return

0;

47.
}  


 
 
 

 
     //优秀代码
#include<stdio.h>
int Test(int m)
{
     int c[4],j,k,temp,a,b;
     c[0]=m;
     c[1]=m/10;
     c[2]=m/100;
     c[3]=m/1000;
     for(j=0;j<3;++j)
        for(k=j+1;k<4;++k)//冒泡排序
        {
           if(c[j]<c[k])//大到小
           {
               temp=c[j];
               c[j]=c[k];
               c[k]=temp;
           }
        }
        a=1000*c[0]+100*c[1]+10*c[2]+c[3];
        b=1000*c[3]+100*c[2]+10*c[1]+c[0];
     return a-b;
}
int main()
{
  int n,m,i,cnt,c[4];
  scanf("%d",&n);
  for(i=0;i<n;++i)
  {
     cnt=1;
     scanf("%d",&m);

     while(m!=6174)
     {
       m=Test(m);
       cnt++;
     }
      printf("%d\n",cnt);
  }
   return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: