鱼C论坛

 找回密码
 立即注册
查看: 1502|回复: 6

[已解决]递归问题

[复制链接]
发表于 2021-10-27 14:03:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目是要求输入一个四位数,让里面数字组成最大值和最小值相减,一直循环下去直到结果重复为止。输入1001,最终结果为6174;
这里不知道是不是我的递归方法用得不对,大佬们帮我看下。
#include<stdio.h>

int num[5];
int result(int m) {
        int e, f;   // 存放余数
        int max, min;
        num[0] = m / 1000; // 千位
        e = m % 1000;
        num[1] = e / 100;  // 百位
        f = e % 100;
        num[2] = f / 10;   // 十位
        num[3] = f % 10;   // 个位

        int i, j;

        // 四位数最大值
        for (i = 0; i < 4; i++) {
                for (j = 0; j < 4 - i - 1; j++) {
                        if (num[j] < num[j + 1]) {
                                int temp = num[j];
                                num[j] = num[j + 1];
                                num[j + 1] = temp;
                        }
                }
        }
        max = num[0] * 1000 + num[1] * 100 + num[2] * 10 + num[3];

        // 四位数最小值
        for (i = 0; i < 4; i++) {
                for (j = 0; j < 4 - i - 1; j++) {
                        if (num[j] > num[j + 1]) {
                                int temp = num[j];
                                num[j] = num[j + 1];
                                num[j + 1] = temp;
                        }
                }
        }
        min = num[0] * 1000 + num[1] * 100 + num[2] * 10 + num[3];

        int cha1 = max - min;   // 求差
        int cha2 = 0;
        if (cha1 != cha2) {   // 不相同递归
                cha2 = cha1;
                return result(cha1);
        }
        else {
                return cha1;
        }
}

int main() {
        int m;
        scanf("%d", &m);
        printf("%d", result(m));
        return 0;
}
最佳答案
2021-10-27 15:34:51
本帖最后由 jackz007 于 2021-10-27 15:51 编辑
a327904410 发表于 2021-10-27 14:21
编写一个程序,输入一个4位的正整数,将组成该数的各位数字重新排列,形成一个最大数和一个最小数,之后 ...


        第42行有错误
        if (cha1 != cha2) {   // 不相同递归
        改为
        if (cha1 != m) {   // 不相同递归
        试试看。
         下面是我写的代码版本,仅供楼主参考
#include <stdio.h>

int foo(int n)
{
        int d[4] = {0} , i , j , k , r = 0 , max , min                    ;
        if(n > 999 && n < 10000) {
                for(k = n , i = 4 ; i ; k /= 10 , i --) d[i - 1] = k % 10 ;
                for(i = 0 ; i < 3 ; i ++) {
                        for(j = i + 1 ; j && d[j] < d[j - 1]; j --) {
                                k = d[j - 1]                              ;
                                d[j - 1] = d[j]                           ;
                                d[j] = k                                  ;
                        }
                }
                max = d[3] * 1000 + d[2] * 100 + d[1] * 10 + d[0]         ;
                min = d[0] * 1000 + d[1] * 100 + d[2] * 10 + d[3]         ;
                if(max - min != n) r = foo(max - min)                     ;
                else r = max - min                                        ;
        }
        return r                                                          ;
}

int main(void)
{
        int n                   ;
        scanf("%d" , & n)       ;
        printf("%d\n" , foo(n)) ;
}
        编译、运行实况:
D:\0002.Exercise\C>g++ -o x x.c

D:\0002.Exercise\C>x
1001
6174

D:\0002.Exercise\C>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-10-27 14:11:44 | 显示全部楼层
        是么叫 "结果重复",请举例说明。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-27 14:21:13 | 显示全部楼层
jackz007 发表于 2021-10-27 14:11
是么叫 "结果重复",请举例说明。

编写一个程序,输入一个4位的正整数,将组成该数的各位数字重新排列,形成一个最大数和一个最小数,之后用最大数减去最小数,得到一个新的正整数(该数一定大于1000)。然后对于这个新的正整数,重复上述步骤,直到该正整数的值不再发生变化。
  例如,假设用户输入的正整数为1001,那么由它所形成的最大数为1100,最小数为11,因此新的正整数为1089。对于1089,由它形成的最大数为9810,最小数为189,因此新的正整数为9621。9621的最大数为9621,最小数为1269,结果为8352,。8352的最大数为8532,最小数为2358,结果为6174。6174的最大数为7641,最小数为1467,结果仍为6174,因此程序结束。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-27 15:34:51 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2021-10-27 15:51 编辑
a327904410 发表于 2021-10-27 14:21
编写一个程序,输入一个4位的正整数,将组成该数的各位数字重新排列,形成一个最大数和一个最小数,之后 ...


        第42行有错误
        if (cha1 != cha2) {   // 不相同递归
        改为
        if (cha1 != m) {   // 不相同递归
        试试看。
         下面是我写的代码版本,仅供楼主参考
#include <stdio.h>

int foo(int n)
{
        int d[4] = {0} , i , j , k , r = 0 , max , min                    ;
        if(n > 999 && n < 10000) {
                for(k = n , i = 4 ; i ; k /= 10 , i --) d[i - 1] = k % 10 ;
                for(i = 0 ; i < 3 ; i ++) {
                        for(j = i + 1 ; j && d[j] < d[j - 1]; j --) {
                                k = d[j - 1]                              ;
                                d[j - 1] = d[j]                           ;
                                d[j] = k                                  ;
                        }
                }
                max = d[3] * 1000 + d[2] * 100 + d[1] * 10 + d[0]         ;
                min = d[0] * 1000 + d[1] * 100 + d[2] * 10 + d[3]         ;
                if(max - min != n) r = foo(max - min)                     ;
                else r = max - min                                        ;
        }
        return r                                                          ;
}

int main(void)
{
        int n                   ;
        scanf("%d" , & n)       ;
        printf("%d\n" , foo(n)) ;
}
        编译、运行实况:
D:\0002.Exercise\C>g++ -o x x.c

D:\0002.Exercise\C>x
1001
6174

D:\0002.Exercise\C>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-27 16:12:46 | 显示全部楼层
本帖最后由 傻眼貓咪 于 2021-10-27 16:20 编辑
#include <stdio.h>
#include <stdbool.h>

int max(int a, int b, int c, int d){ return (a >= b && a >= c && a >= d) ? a : (b >= a && b >= c && b >= d) ? b : (c >= a && c >= b && c >= d) ? c : d; }

bool kaprekar(int num) // Kaprekar number
{
    int a, b, c, d;
    a = num/1000;
    b = (num%1000)/100;
    c = (num%100)/10;
    d = (num%10);
    return (max(a, b, c, d)*4-(a+b+c+d)) > 1 ? true : false;
}

int main()
{
    int num;
    scanf("%d", &num);
    printf("%d", kaprekar(num) ? 6174 : 0); // 答案必然是 6174 或 0
    return 0;
}
卡布列克常数
任意一个不是由完全相同数字组成的四位数,如果对它们的每位数字重新排序,组成一个较大的数和一个较小的数,
然后用较大数减去较小数,差不够四位数时补零,类推下去,最后将变成一个固定的数:6174,这就是卡布列克常数(Kaprekar number)
**条件:4个数字不能有4个相同数字
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-27 19:14:36 | 显示全部楼层
jackz007 发表于 2021-10-27 15:34
第42行有错误

        改为

确实是42有误,懂了- -前面int个0递归回来还是0,我又傻了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-27 19:17:11 | 显示全部楼层
傻眼貓咪 发表于 2021-10-27 16:12
本帖最后由 傻眼貓咪 于 2021-10-27 16:20 编辑

卡布列克常数

感谢,辛苦了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 19:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表