Vijos-P1024-卡布列克圆舞曲(c++ && 简单模拟)

P1024卡布列克圆舞曲
Accepted
标签: 模拟

描述

卡布列克是一位数学家,他在研究数字时发现:任意一个不是用完全相同数字组成的四位数,如果对它们的每位数字重新排序,组成一个较大的数和一个较小的数,然后用较大数减去较小数,差不够四位数时补零,类推下去,最后将变成一个固定的数: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)                          			//检查是否出现循环节或者循环点
{
    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]);         			 //直接输出循环节
        }
        printf("\n");
        return 1;
    }
    
}
double pow1(int n)					      //数组下标是几就返回10的几次方
{
    if(n==0)
        return 1;
    else
        return pow1(n-1)*10;
}
double confuse(double number)			              //求最大值最小值相减构成递归
{
    char ch[150];
    int temp;
    double max=0,min=0;
    sprintf(ch,"%.0f",number);                                   //初始化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;
}


你可能感兴趣的:(C++,难题,vijos,算法不错)