标题:卡不列克常数问题求思路
只看楼主
komorebi0110
Rank: 2
来 自:上海
等 级:论坛游民
帖 子:145
专家分:17
注 册:2019-11-23
结帖率:96.88%
已结贴  问题点数:20 回复次数:8 
卡不列克常数问题求思路
最近, Cuber QQ 了解了 卡布列克常数 。
卡布列克是一位数学家,他在研究数字时发现:任意一个不是用完全相同数字组成的四位数,如果对它们的每位数字重新排序,组成一个最大的数和一个最小的数,然后用最大数减去最小数,差不够四位数时补零,类推下去,最后将变成一个固定的数:6174 ,这就是卡布列克常数。
例如:
4321−1234=3087
8730−378=8352
8532−2358=6174
7641−1467=6174

Cuber QQ 想用程序来验证,现在会输入一个符合条件的四位数,然后输出验证运算过程。
输入格式
输入共 1 行,为任意一个不是用完全相同数字组成的四位数。
输出格式
输出包含变为卡布列克常数的运算过程,由若干行组成,每行是一个算式,不含空格。
样例
Input
4321
Output
4321-1234=3087
8730-378=8352
8532-2358=6174

搜索更多相关主题的帖子: 思路 位数 输出 组成 常数 
2019-12-24 11:51
komorebi0110
Rank: 2
来 自:上海
等 级:论坛游民
帖 子:145
专家分:17
注 册:2019-11-23
得分:0 
如果只是给字符串排序的话我可以找出最大的和最小的 但是这种题目遇到0了该怎么办啊

我想要两颗西柚。
2019-12-24 11:52
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
得分:6 
//无意中在百度中看到原题你看看能解决吧,如果输入0结果没意义0000-0还是0
#include<stdio.h>
void vr6174(int);
void parse_sort(int num,int *each);
void max_min(int *each,int *max,int *min);
void parse_sort(int num,int *each);
int count=0;
void main()
{
int n;
printf("Enter a number:");
scanf("%d", &n); /*输入任意正整数*/
vr6174(n); /*调用函数进行验证*/
}

void vr6174(int num)
{
int each[4],max,min;
if(num!=6174&&num) /*若不等于74且不等于0则进行卡布列克运算*/
{
parse_sort(num,each); /*将整数分解,数字存入each数组中*/
max_min(each,&max,&min); /*求数字组成的最大值和最小值*/
num=max-min; /*求最大值和最小值的差*/
printf("[%d]: %d-%d=%d\n",++count,max,min,num); /*输出该步计算过程*/
vr6174(num); /*递归调用自身继续进行卡布列克运算*/
}
}
void parse_sort(int num,int *each)
{
int i,*j,*k,temp;
for(i=0;i<=4;i++) /*将NUM分解为数字*/
{
j=each+3-i;
*j=num%10;
num/=10;
}
for(i=0;i<3;i++) /*对各保数字从小到大进行排序*/
for(j=each,k=each+1;j<each+3-i;j++,k++)
if(*j>*k) { temp=*j;*j=*k;*k=temp;}
return;
}
void max_min(int *each,int *max,int *min) /*将分解的数字还原为最大整数和最小整数*/
{
int *i;
*min=0;
for(i=each;i<each+4;i++) /*还原为最小的整数*/
*min=*min*10+*i;
*max=0;
for(i=each+3;i>=each;i--) /*还原为最大的整数*/
*max=*max*10+*i;
return;
}

把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2019-12-24 14:28
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
得分:0 
我没排版,你帮忙排一下

把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2019-12-24 14:30
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:7 
程序代码:
#include <stdio.h>

void Kablek( unsigned n )
{
    while( n!=0 && n!=6174 )
    {
        unsigned ds[] = { n/1000%10, n/100%10, n/10%10, n/1%10 };
        for( size_t i=0; i!=3; ++i )
        {
            for( size_t j=0; j!=3-i; ++j )
            {
                if( ds[j] < ds[j+1] )
                {
                    unsigned tmp = ds[j];
                    ds[j] = ds[j+1];
                    ds[j+1] = tmp;
                }
            }
        }

        unsigned a = ds[0]*1000 + ds[1]*100 + ds[2]*10 + ds[3]*1;
        unsigned b = ds[0]*1 + ds[1]*10 + ds[2]*100 + ds[3]*1000;
        n = a - b;
        printf( "%u-%u=%u\n", a, b, n );
    }
}

int main( void )
{
    unsigned n;
    scanf( "%u", &n );

    Kablek( n );
}
收到的鲜花
  • 叶纤2019-12-24 14:58 送鲜花  2朵   附言:可以的话用C++翻译一下,好吗
2019-12-24 14:51
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
可以的话用C++翻译一下,好吗
这么简单,你自己写呀

程序代码:
#include <iostream>
#include <algorithm>
#include <numeric>
using namespace std;

void Kablek( unsigned n )
{
    while( n!=0 && n!=6174 )
    {
        unsigned ds[] = { n/1000%10, n/100%10, n/10%10, n/1%10 };
        sort( ds, ds+4 );
        const unsigned bases[] = { 1, 10, 100, 1000 };
        unsigned a = inner_product( cbegin(ds), cend(ds), bases, 0u );
        unsigned b = inner_product( crbegin(ds), crend(ds), bases, 0u );
        n = a - b;
        cout << a << '-' << b << '=' << n << '\n';
    }
}

int main( void )
{
    unsigned n;
    cin >> n;

    Kablek( n );
}

2019-12-24 15:30
自学的数学
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:46
帖 子:967
专家分:4146
注 册:2017-11-15
得分:7 
这个问题我还是比较喜欢的,还有更复杂的,现在先把本题解决了吧:
程序代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int len=1;
int sum(int n){
    int a[5]={0},i;
    for( i=0;i<5;i++){
        a[i]=n%10;
        n=n/10;
    }
    sort(a,a+4);
    int max,min;
    int b;
    max=a[3]*1000+a[2]*100+a[1]*10+a[0];
    min=a[3]+a[2]*10+a[1]*100+a[0]*1000;
    b=max-min;
    if(b==6174){
        printf("6174 ");
        printf("\n");
        return len;
    }else{
        len++;
        printf("%d ",b);
        return sum(b);
    }

 
}
int main(){
    int n;
    while(cin>>n){
    printf("%d\n",sum(n));
    len=1;
    }
    return 0;
}
2019-12-24 15:36
自学的数学
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:46
帖 子:967
专家分:4146
注 册:2017-11-15
得分:0 
7楼发表的哦是四位数的数学黑洞,还有五位数的数学黑洞,如下:
程序代码:
#include <iostream>
#include<Set>
#include<Vector>
#include<algorithm>
#include<Math.h>
#include<string>
#include<sstream>

 
using namespace std; 

 
int GetNum(int num);//获取最大和最小之间的差
bool FindTheSame(vector<int> a,int ch,int ah,int& c);////判断是否有循环圈存在,只需要判断是否有连续的两个数都相等即可判定其为黑洞循环
bool isAllDifferent(vector<int> a,int start,int end,vector<int> cp);//排除数字顺序不同而出现的情况
bool isNum=false;

 
int main(int argc, char** argv) {
    set<string> a;//用来存储结果的集合
    set<string>::iterator pos;
    vector<int> check;//用来存储出现在结果中的所有数,以保证符合题目要求,不考虑数字出现的顺序(当然,这个可以根据用户使用需要自行更改了)
    for(int n=10000;n<=99999;n++){
        vector<int> result;
        string str="[";
        int Key;
        int i=0;
        int set;
        Key=GetNum(n);
        if(result.empty()){
            result.push_back(Key);
            Key=GetNum(Key);
            i++;
        }
        while(!FindTheSame(result,Key,i,set)){
            result.push_back(Key);
            Key=GetNum(Key);
            i++;
        }
        if(isAllDifferent(result,set,i-1,check)){
            for(int q=set;q<i-1;q++){
                check.push_back(result[q]);
                stringstream ss;
                string str1;
                ss<<result[q];
                str1=ss.str()+",";
                str+=str1;
            }//上一个FOR循环用来将结果转化为string类型存储到集合a里,使用集合可以减去我们手动判断的代码
            str.replace(str.length()-1,1,"]");
            a.insert(str);
        }
    }
    for(pos=a.begin();pos!=a.end();++pos){
        cout<<*pos<<endl;
    }
    return 0;
}

 
int GetNum(int num){
    vector<int> start;
    int temp;
    int num1=0;
    int num2=0;
    if(num<10000)
        isNum=true;
    for(int i=0;i<5;i++){
        if(isNum){
            start.push_back(0);
            isNum=false;
        }else{
            start.push_back(num%10);
            num/=10;
        }
    }
    sort(start.begin(),start.end());//使用STL内部的快排函数直接对向量排序
    for(int i=0;i<5;i++){
        num1+=start[4-i]*pow(10,4-i);
        num2+=start[i]*pow(10,4-i);
    }
    temp=num1-num2;
    return temp;
}

 
bool FindTheSame(vector<int> a,int ch,int ah,int& c){
    for(int i=0;i<a.size();i++){
        if(ch==a[i]){
            if(i-1>=0){
                if(a[i-1]==a[ah-1]){//只要有连续的两个数都相等即可判定其为黑洞循环
                    c=i-1;
                    return true;
                }
            }
        }
    }
    return false;
}

 
bool isAllDifferent(vector<int> a,int start,int end,vector<int> cp){
    for(int i=0;i<cp.size();i++){
        for(int j=start;j<end;j++){
            if(cp[i]==a[j])
                return false;
        }
    }
    return true;
}
收到的鲜花
  • 叶纤2019-12-24 18:08 送鲜花  2朵   附言:cow — x
2019-12-24 15:44
叶纤
Rank: 8Rank: 8
等 级:禁止访问
威 望:1
帖 子:658
专家分:848
注 册:2019-11-22
得分:0 
7楼出了个黑洞题,要知道代码是人写出来的,7楼的脑洞简直深不可测,称为黑洞始祖都不为过,先送2朵花花,6楼的代码附加物理伤害,伤害爆表,称为黑洞中的齐天大圣不为过。不过你五楼的代码有治疗作用,回了半管血,我现在要用后半管血继续看你6楼看似一样又不一样的代码

把学习时间浪费在混坛上是傻瓜行为,更何况自己的水平连一两都没到。
2019-12-24 18:20



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-498596-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.438485 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved