标题:对超长正整数的处理?
只看楼主
逢考必过阿俊
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2022-1-15
结帖率:50%
已结贴  问题点数:20 回复次数:16 
对超长正整数的处理?
大家好,请问这道题目怎么做?
(似乎字符数组可以解决,不过我没想出解法)

搜索更多相关主题的帖子: 正整数 处理 数组 字符 
2022-03-23 19:28
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:10 
第一步。n位的整数,各位之和最小是1,最大是9n。
100位的整数,各位之和最大才是900。
前缀从1遍历到900。

第二步。假设100位的整数各位之和是199,199-1-9-9=180,也就是说后97位之和是180。
后97位中有a个9,b个8,c个7,……,通过循环算出每个组合。

第三步。a个9,b个8,c个7,…… 一共可以组成 97! / a! / b! / c! / ...... 种不同的97位数。

看起来最后一步有问题,数值太大,我得再想想
2022-03-23 21:37
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
第三步的计算,只需要记录1到97这97个数中每一个数的因子和数目,然后乘就是因子数目想加,除就是因子数目相减。
最后所有留下的因子相乘,乘的过程中,中间结果不停地模除 10^9+7 以避免溢出
2022-03-24 22:04
纯蓝之刃
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:76
帖 子:554
专家分:3690
注 册:2019-7-29
得分:10 
我先来一个,不知道有没有bug,仅供参考。
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void print_value(int count,int current_len,const char *a)
{
    char c_str[]={1,0,0,0,0,0,0,0,0,7},c_len,ch;
    char b[110];
    int i,j,offset=0;

    c_len=sizeof(c_str);
    memset(b,0,sizeof(b));
    printf("%d ",count);
    for(i=current_len-1,j=0;i>=0;i--)
    {
        printf("%d",a[i]);
        b[j++]=a[i];
    }

    while(1)
    {
        if(offset>current_len-c_len)
            break;

        if(memcmp(b+offset,c_str,c_len)>=0)
        {
            for(i=c_len-1+offset,ch=0;i>=0+offset;i--)
            {
                ch=ch+b[i]-c_str[i-offset];
                if(ch>=0)
                {
                    b[i]=ch;
                    ch=0;
                }
                else
                {
                    b[i]=ch+10;
                    ch=-1;
                }
            }
            for(i=0;i<current_len;i++)
            {
                if(b[i]!=0)
                {
                    offset=i;
                    break;
                }
            }
        }
        else
        {
            break;
        }
    }
    printf(" ");
    for(i=offset;i<current_len;i++)
    {
        printf("%d",b[i]);
    }
    printf("\n");
}

int main()
{
    char a[100],b[5];
    int i,j,n,sum,count=0,current_bit=0,current_len;

    printf("请输入一个正整数(长度大于0,小等于100):");
    scanf("%u",&n);

    memset(a,0,sizeof(a));
    current_len=1;

    while(1)
    {
        for(i=0;i<=9;i++)
        {
            a[current_bit]=i;

            for(j=0,sum=0;j<current_len;j++)
                sum+=a[j];

            memset(b,0,sizeof(b));
            sprintf(b,"%d",sum);
            for(j=0;j<strlen(b);j++)
            {
                if(b[j]!=a[current_len-j-1]+'0')
                    break;
            }
            if(j==strlen(b) && a[current_len-1]!=0)
            {
                count++;
                print_value(count,current_len,a);
            }
        }

        while(1)
        {
            if(a[current_bit]<9)
            {
                a[current_bit]++;
                current_bit=0;
                break;
            }
            else
            {
                current_bit++;
                if(current_bit>=current_len)
                {
                    current_len++;
                    current_bit=0;
                    memset(a,0,sizeof(a));
                    break;
                }
            }
        }
        if(current_len>n)
            break;
    }

    return 0;
}


[此贴子已经被作者于2022-3-25 11:01编辑过]


一沙一世界,一花一天堂。无限掌中置,刹那成永恒。
2022-03-25 10:56
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
回复 4楼 纯蓝之刃
如果是 3位数 abc,
那么 a+b+c = a 或 a+b+c = 10a+b
前者解出来是 b=0 && c=0,也就是 100、200、300、……、900
后者解出来是 a=1 && c=9,也就是 109、119、129、……、199
一共19个
2022-03-25 15:08
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
f(1)=10
f(2)=9
f(3)=19
f(4)=119
f(5)=1119
f(6)=11119
……
看来,规律性很强,只要再模除 10^9+7 就行了
2022-03-25 15:25
纯蓝之刃
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:76
帖 子:554
专家分:3690
注 册:2019-7-29
得分:0 
回复 5楼 rjsp
之前的有bug,改了一下,感觉应该差不多了。
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void print_value(int count,int current_len,const char *a)
{
    char c_str[]={1,0,0,0,0,0,0,0,0,7},c_len,ch;
    char b[110];
    int i,j,offset=0;

    c_len=sizeof(c_str);
    memset(b,0,sizeof(b));
    printf("%d ",count);
    for(i=current_len-1,j=0;i>=0;i--)
    {
        printf("%d",a[i]);
        b[j++]=a[i];
    }

    while(1)
    {
        if(offset>current_len-c_len)
            break;

        if(memcmp(b+offset,c_str,c_len)>=0)
        {
            for(i=c_len-1+offset,ch=0;i>=0+offset;i--)
            {
                ch=ch+b[i]-c_str[i-offset];
                if(ch>=0)
                {
                    b[i]=ch;
                    ch=0;
                }
                else
                {
                    b[i]=ch+10;
                    ch=-1;
                }
            }
            for(i=0;i<current_len;i++)
            {
                if(b[i]!=0)
                {
                    offset=i;
                    break;
                }
            }
        }
        else
        {
            break;
        }
    }
    printf(" ");
    for(i=offset;i<current_len;i++)
    {
        printf("%d",b[i]);
    }
    printf("\n");
}

int main()
{
    char a[100],b[5];
    int i,j,k,n,sum,count=0,current_bit=0,current_len,count_temp=0;

    printf("请输入一个正整数(长度大于0,小等于100):");
    scanf("%u",&n);

    memset(a,0,sizeof(a));
    current_len=1;

    while(1)
    {
        for(i=0;i<=9;i++)
        {
            a[current_bit]=i;

            for(j=0,sum=0;j<current_len;j++)
                sum+=a[j];

            memset(b,0,sizeof(b));
            sprintf(b,"%d",sum);
            for(j=0;j<strlen(b);j++)
            {
                if(b[j]!=a[current_len-j-1]+'0')
                    break;
            }
            if(j==strlen(b) && a[current_len-1]!=0)
            {
                count++;
                print_value(count,current_len,a);
            }
        }

        while(1)
        {
            if(a[current_bit]<9)
            {
                a[current_bit]++;
                for(i=0;i<current_bit;i++)
                    a[i]=0;
                current_bit=0;
                break;
            }
            else
            {
                current_bit++;
                if(current_bit>=current_len)
                {
                    current_len++;
                    current_bit=0;
                    memset(a,0,sizeof(a));
                    a[current_len-1]=1;
                    break;
                }
            }
        }
        if(current_len>n)
            break;
    }

    return 0;
}

一沙一世界,一花一天堂。无限掌中置,刹那成永恒。
2022-03-26 14:29
逢考必过阿俊
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2022-1-15
得分:0 
回复 6楼 rjsp
谢谢你!如果能找到规律就太好了!
不过,我按照这种规律解题,提交结果显示是wrong answer(部分错误)。
请问,我的程序是哪里出错了呢?

#include <stdio.h>
#include <math.h>
int main()
{
    int n = 0;
    unsigned long long m = 0;
    scanf("%d", &n);

    if (n == 1)
    {
        m = 10;
    }   
    else if (n == 2)
    {
        m = 9;
    }
    else
    {
        m = 9;
        for (int i = 1; i <= n - 2; ++i)
        {
            m += (int)pow(10, i);
            m = m % ((int)pow(10, 9) + 7);
        }
    }

    printf("%llu\n", m);
    return 0;
}
2022-03-27 17:07
逢考必过阿俊
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2022-1-15
得分:0 
回复 7楼 纯蓝之刃
谢谢你!写了好长的代码,辛苦你了!
不过,rjsp回复说这道题的答案是有规律的,我想试试用规律输出答案。
2022-03-27 17:16
逢考必过阿俊
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2022-1-15
得分:0 
回复 8楼 逢考必过阿俊
出错原因应该是:m在取模之前就已经溢出

我把for循环改了一下
for (int i = 1; i <= n - 2; ++i)
        {
            m += (int)pow(10, i) % ((int)pow(10, 9) + 7);
        }

f(11)之后的结果仍然是错误的,为什么呀?

[此贴子已经被作者于2022-3-27 17:57编辑过]

2022-03-27 17:40



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




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

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