P1024卡布列克圆舞曲
标签:模拟
描述
卡布列克是一位数学家,他在研究数字时发现:任意一个不是用完全相同数字组成的四位数,如果对它们的每位数字重新排序,组成一个较大的数和一个较小的数,然后用较大数减去较小数,差不够四位数时补零,类推下去,最后将变成一个固定的数:6174,这就是卡布列克常数。
例如:4321-1234=3087
8730-378=8352
8532-2358=6174
7641-1467=6147
如果K位数也照此办理,它们不是变成一个数,而是在几个数字之间形成循环,称作卡布列克圆舞曲。例如对于五位数54321:
54321-12345=41976
97641-14679=82962
98622-22689=75933
97533-33579=63954
96543-34569=61974
97641-14679=82962
我们把82962 75933 63954 61974称作循环节,即卡布列克圆舞曲。
格式
输入格式
文件包含若干行,每行为一个待求“卡布列克圆舞曲”的起始整数(小于maxlongint)
输出格式
每行为对应整数的循环节,数据之间用空格隔开。
样例1
样例输入1[复制]
4321 54321
样例输出1[复制]
6174 82962 75933 63954 61974
限制
各个测试点1s
来源
Xiaomengxian
高一的第二次考试题
博主决定不总是在HDU水下去了!重返Vijos(其实就是换个地方水.....)不过好歹,Vijos的题做起来脑袋痛.....今天我可是花了不少时间来弄懂这道题.....里面的初中生高中生Oier太厉害了.....哥给跪了......Orz!!!
感谢talent123前辈提供的精妙绝伦的算法!(在我看来就是这样!)
你看上面写的是高一第二次考试题......大学狗被高中生完爆!
本题注意:输入的数据也得考虑,它也可能是循环节!
#include<iostream> #include<cstdio> #include<cstring> using namespace std; double number,circle[1000]; int check_print(int i) <span style="white-space:pre"> </span>//检查是否出现循环节或者循环点 { int j; for(j=0;j<i;j++) { if(circle[j]==circle[i]) break; } if(j==i) return 0; else { for(;j<i;j++) { printf("%.0lf ",circle[j]); <span style="white-space:pre"> </span> //直接输出循环节 } printf("\n"); return 1; } } double pow1(int n)<span style="white-space:pre"> </span> //数组下标是几就返回10的几次方 { if(n==0) return 1; else return pow1(n-1)*10; } double confuse(double number)<span style="white-space:pre"> </span> //求最大值最小值相减构成递归 { char ch[150]; int temp; double max=0,min=0; sprintf(ch,"%.0f",number); <span style="white-space:pre"> </span> //初始化ch数组 int i,j; for(i=0;i<strlen(ch);i++) { for(j=0;j<strlen(ch)-i-1;j++) if(ch[j]>ch[j+1]) { temp=ch[j]; ch[j]=ch[j+1]; ch[j+1]=temp; } } for(i=0;i<strlen(ch);i++) { max+=pow1(i)*(ch[i]-'0'); min+=pow1(strlen(ch)-i-1)*(ch[i]-'0'); } return max-min; } void femain(double number) { int i=0; for(i=0;;i++) { circle[i]=number; if(check_print(i)==1) break; else { number = confuse(number); } } } int main() { while(1) { if(scanf("%lf",&number)==-1)break; else { femain(number); } } return 0; }
时间: 2024-11-05 06:31:09