2017 山东 NOIP 小学组复赛试题3——6174 问题

6174 问题

【问题描述】

假设你有一个各位数字不完全相同的四位数,把所有的数字从大到小排序后得到 a,从小到大排序后得到 b,然后用 a-b 替换原来这个数,并且继续操作。
例如,从 1234 出发,依次可以得到 4321-1234=3087、8730-378=8352、8532-2358=6174、7641-1467=6174,又回到了它自己!现在请你写一个程序来判断一个四位数经过多少次这样的操作能出现循环。
比如输入 1234 执行顺序是 1234->3087->8352->6174->6174,输出结果是 4。

【输入】

输入文件名为 kaprekar.in。
输入文件第一行是一个正整数 n,表示有 n 组测试数据,
接下来的 n 行,每行一个各位数字不完全相同的四位数。

【输出】

输出文件名为 kaprekar.out。
对于每组测试数据输出一行,每行中只有一个整数,表示经过多少次操作
才出现循环。

【输入输出样例】

kaprekar.in kaprekar.out
1
1234
4

【数据范围】

对于 50%的数据:0 对于 100%的数据:0

题目解析

由题目中已知,我们需要输入的n个数据均为四位数,需要把这个四位数进行从大到小排序,得到较大的数a,再进行从小到大排序,得到较小的数b。不断重复上述操作,直至所得的数出现循环,即出现上一次的他自己,这里可以用到while循环。

代码如下

#include
using namespace std;
int a[6];
//solve()函数完成分离位数、排序、数字重组,以及求差值的工作
int solve(int x){
	memset(a,0,sizeof(a));
	int s1=0,s2=0,i=0;
	a[1]=x%10;
    a[2]=x/10%10;
    a[3]=x/100%10;
    a[4]=x/1000%10;
	sort(a+1,a+5);
	s1=a[1]*1000+a[2]*100+a[3]*10+a[4];
	s2=a[4]*1000+a[3]*100+a[2]*10+a[1];
	return s2-s1;	
}
int main(){	
	int n,x;
	scanf("%d",&n);
	while(n--){
		scanf("%d",&x);
		int s=0,x1=0,y=0;
		//判断是否出现重复的两个数
		while(x!=y){
			y=x;
			s++;
			x=solve(x);//调用函数
		}	
		printf("%d\n",s);	
	}
	return 0;
}

你可能感兴趣的:(算法,c++,信息学奥赛)