POJ 2305大数求余

一开始是的想法是用减法代替除法,一直减到被减数小于减数,所得的被减数就是余数。为了方便编程,还在减法中对齐了被减数和减数的位数。但过程还是比较麻烦,会超时。

 1 #include "stdafx.h"
 2 #include<string>
 3 #include<iostream>
 4 using namespace std;
 5 int b;
 6 string decrease(string p, string cut)
 7 {
 8     int diff=p.size()-cut.size();
 9     if(diff!=0)
10     {
11         cut=string(diff,‘0‘)+cut;
12     }
13     int len=p.size()-1;
14     int flag=0;
15     for(int i=len;i>=0;i--)
16     {
17         if(p[i]>=cut[i])
18             p[i]=p[i]-cut[i]+‘0‘;
19         else if(p[i]<cut[i])
20         {
21             if(p[i-1]>=‘1‘)
22             {
23                 p[i-1]-=1;
24                 p[i]=p[i]+b-cut[i]+‘0‘;
25             }
26             else if(p[i-1]==‘0‘)
27             {
28                 int j=i-2;
29                 while(p[j]==‘0‘)
30                     p[j--]=‘0‘+b-1;
31                 p[j]-=1;
32                 p[i-1]=0+b-1;
33                 p[i]=p[i]+b-cut[i]+‘0‘;
34             }
35         }
36         if(p[i]!=‘0‘)
37             flag=i;
38     }
39     return p.substr(flag,len+1-flag);
40 }
41 int _tmain(int argc, _TCHAR* argv[])
42 {
43     string p,m;
44     while(1)
45     {
46         cin>>b;
47         if(b==0)
48             break;
49         cin>>p>>m;
50         while(p.size()>m.size()||(p.size()==m.size()&&p>=m))
51         {
52             int diff=p.size()-m.size();
53             string add1(diff,‘0‘);
54             string cut=m+add1;
55             if(p>=cut)
56             {
57                 while(p.size()==cut.size()&&p>=cut)
58                     p=decrease(p,cut);
59             }
60             else if(p<cut)
61             {
62                 string add2(diff-1,‘0‘);
63                 cut=m+add2;
64                 while(p.size()>cut.size())
65                     p=decrease(p,cut);
66             }
67         }
68         cout<<p<<endl;
69     }
70     return 0;
71 }

后来参考了http://blog.sina.com.cn/s/blog_7865b08301010fzf.html中的做法,发现了“一次求余数和多次求余数的效果是一样的”这个结论,具体体现在以下一段循环代码:

for(int i=0;i<p.length();i++)
{
     r=r*b+p[i]-‘0‘;
     r %= m;
}

觉得十分巧妙。然后,注意strtol()函数的调用方法。AC代码:

#include "stdafx.h"
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;

void print(int r,int b)
{
    if(r)
    {
        print(r/b,b);
        printf("%d",r%b);
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    int b,m,r;
    string p,ms;
    while(scanf("%d",&b),b)
    {
        cin>>p>>ms;
        m=strtol(ms.c_str(),0,b);
        r=0;
        for(int i=0;i<p.length();i++)
        {
            r=r*b+p[i]-‘0‘;
            r %= m;
        }
        if(r)
        {
            print(r,b);
            cout<<endl;
        }
        else
            cout<<‘0‘<<endl;
    }
    return 0;
}
时间: 2024-10-20 11:04:04

POJ 2305大数求余的相关文章

POJ 2635 The Embarrassed Cryptographer(大数求余)

题意:给出一个大数,这个大数由两个素数相乘得到,让我们判断是否其中一个素数比L要小,如果两个都小,输出较小的那个. 分析:大数求余的方法:针对题目中的样例,143 11,我们可以这样算,1 % 11 = 1:      1×10 + 4 % 11 = 3:      3×10 + 3 % 11 = 0;我们可以把大数拆成小数去计算,同余膜定理保证了这个算法的这正确性,而且我们将进制进行一定的扩大也是正确的. 注意:素数打标需要优化,否则超时.   进制需要适当,100和1000都可以,10进制超

大数求余

1 /**2016中国大学生程序设计网络赛赛HDU 2 1001大数求余 3 */ 4 5 #include "iostream" 6 #include "cstdio" 7 #include "cstring" 8 using namespace std; 9 char s[100000002]; 10 int main() { 11 12 int t=1; 13 while(~scanf("%s", &s)) {

nyoj 803 A/B Problem(大数除小数&amp;&amp;大数求余小数)

这道题 也就是大数除或者求模小数,不过听说java处理大数很方便,可是java学的一塌糊涂..有心人用java做吧 奉上c语言代码: #include <stdio.h> #include <string.h> int main() { char a[1000],c[1000],ch; int b,i,j,r; while(scanf("%s %c %d",a,&ch,&b)!=EOF)//a是存贮大数,ch存贮运算符,b是小数 { r=0; i

大数求余简单办法(水)

Prepared for New Acmer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7477    Accepted Submission(s): 2826 Problem Description 集训进行了将近2个礼拜,这段时间以恢复性训练为主,我一直在密切关注大家的训练情况,目前为止,对大家的表现相当满意,首先是绝大部分队员

Large Division (大数求余)

Given two integers, a and b, you should check whether a is divisible by b or not. We know that an integer a is divisible by an integer b if and only if there exists an integer c such that a = b * c. Input Input starts with an integer T (≤ 525), denot

poj 2305 Basic remains 高精度取余

题意: 裸的高精度取余. 分析: http://blog.csdn.net/sepnine/article/details/44092055有poj 1220任意进制转换的代码,这题用到其中的一部分,可作对比. 代码: //poj 2305 //sep9 #include <iostream> using namespace std; int b,m; char s1[1024],s2[16],ans[16]; int p[1024]; int main() { while(scanf(&qu

如何运用同余定理求余数【hdoj 1212 Big Number【大数求余数】】

Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5930    Accepted Submission(s): 4146 Problem Description As we know, Big Number is always troublesome. But it's really important in our

取模和求余的区别

通常情况下取模运算(mod)和求余(rem)运算被混为一谈,因为在大多数的编程语言里,都用'%'符号表示取模或者求余运算.在这里要提醒大家要十分注意当前环境下'%'运算符的具体意义,因为在有负数存在的情况下,两者的结果是不一样的. 对于整型数a,b来说,取模运算或者求余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余数: r = a - c*b. 求模运算和求余运算在第一步不同: 取模求余运算在取c的值时,向0 方向舍入(fix()函数): 而求余取模运算在计算c的值时,向

求模和求余(附加C语言实现)

求模和求余的总体计算步骤如下: 1.求整数商  c = a/b 2.计算模或者余数 r = a - c*b 求模和求余的第一步不同,求余在取c的值时向0方向舍入;取模在计算c的值时向无穷小方向舍入. C语言实现 //取余 int rem(int a, int b) { int c = a * 1.0 / b; return (a - c * b); } //求模 int mod(int a, int b) { int c = floor(a * 1.0 / b); //#include <mat