信息学奥赛一本通 2.1:高精度计算

​第二部分 基础算法

第一章 高精度计算

1307 高精度乘法
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void init(int a[]) {
    string s;
    cin >> s;

    a[0] = s.size();
    for (int i = 1; i <= a[0]; i ++ ) {
        a[i] = s[a[0]-i] - '0';
    }
}

void dy(int a[]) {
    for (int i = a[0]; i >= 1; i --) {
        cout << a[i];
    }

    cout << endl;
}

//高精度 a * 高精度 b = 高精度 c
void mul2(int a[], int b[], int c[]) {
    for (int i = 1; i <= a[0]; i ++ ) {
        int t = 0;
        for (int j = 1; j <= b[0]; j ++ ) {
            t += c[i+j-1] + a[i]*b[j];
            c[i+j-1] = t % 10;
            t /= 10;
        }
        if (t) c[i+b[0]] = t;
    }

    c[0] = a[0] + b[0];
    while(!c[c[0]] && c[0] > 1) c[0] -- ;
}

int main() {
    init(a);
    init(b);

    mul2(a, b, c);

    dy(c);

    return 0;
}
1308 高精除
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void init(int a[]) {
    string s;
    cin >> s;

    a[0] = s.size();
    for (int i = 1; i <= a[0]; i ++ ) {
        a[i] = s[a[0]-i] - '0';
    }
}

void dy(int a[]) {
    for (int i = a[0]; i >= 1; i --) {
        cout << a[i];
    }

    cout << endl;
}

//高精度 a - 高精度 b = 高精度 c
void sub(int a[], int b[], int c[]) {
    int t = 0;
    c[0] = a[0];

    for (int i = 1; i <= c[0]; i ++ ) {
        t = a[i] - b[i] - t;
        c[i] = (t + 10) % 10;
        t = t < 0 ? 1 : 0;
    }
    while (!c[c[0]] && c[0] > 1) c[0] -- ;
}

//如果高精度 a > 高精度 b,返回 1
//如果高精度 a < 高精度 b,返回 -1
//如果高精度 a = 高精度 b,返回 0
int cmp(int a[], int b[]) {
    while (!a[a[0]] && a[0] > 1) a[0] -- ;
    while (!b[b[0]] && b[0] > 1) b[0] -- ;

    if (a[0] > b[0]) return 1;
    if (a[0] < b[0]) return -1;
    for (int i = a[0]; i >= 1; i -- ) {
        if (a[i] > b[i]) return 1;
        if (a[i] < b[i]) return -1;
    }
    return 0;
}

//高精度 a * 低精度 x = 高精度 c
void mul(int a[], int x, int c[]) {
    int t = 0;
    c[0] = a[0];

    for (int i = 1; i <= c[0]; i ++ ) {
        t += a[i] * x;
        c[i] = t % 10;
        t /= 10;
    }

    while (t) c[++c[0]] = t % 10, t /= 10;
    while (!c[c[0]] && c[0] > 1) c[0] -- ;
}

//高精度 a / 低精度 x = 高精度 c,余数为 r
void div(int a[], int x, int c[], int &r) {
    r = 0;
    c[0] = a[0];

    for (int i = c[0]; i >= 1; i -- ) {
        r = r * 10 + a[i];
        c[i] = r / x;
        r %= x;
    }

    while (!c[c[0]] && c[0] > 1)  c[0] -- ;
}

//高精度 a / 高精度 b = 高精度 c,余数为 r
void div2(int a[], int b[], int c[]) {
    c[0] = max(a[0] - b[0] + 1, 1);

    while(b[0] < a[0]) mul(b, 10, b);

    for (int i = c[0]; i >= 1; i -- ) {
        while (cmp(a,b) != -1) {
            c[i] ++ ;
            sub(a, b, a);
        }
        int r;
        div(b, 10, b, r);
    }

    while (!c[c[0]] && c[0] > 1)  c[0] -- ;
}

int main() {
    init(a);
    init(b);

    div2(a, b, c);

    dy(c);
    dy(a);

    return 0;
}
1309 回文数
#include 
using namespace std;

const int N = 1e5;
int a[N], c[N], n, cnt = 0;
string m;

void add() {
    int t = 0;

    for (int i = 1, j = a[0]; i <= a[0]; i ++, j -- ) {
        t = t + a[i] + a[j];
        c[i] = t % n;
        t /= n;
    }
    if (t) c[++a[0]] = t;

    for (int i = 1; i <= a[0]; i ++ ) {
        a[i] = c[i];
    }
}

bool isPalindromic() {
    for (int i = 1, j = a[0]; i < j; i ++, j -- ) {
        if (a[i] != a[j]) return false;
    }
    return true;
}

int main() {
    cin >> n >> m;

    a[0] = m.size();
    for (int i = m.size(); i >= 1; i -- ) {
        char ch = m[a[0] - i];
        if (ch >= 'A') a[i] = ch - 'A' + 10;
        else a[i] = ch - '0';
    }

    bool res = isPalindromic();
    while (!res && cnt <= 30) {
        add();
        cnt ++ ;
        res = isPalindromic();
    }

    if (cnt <= 30) cout << cnt;
    else cout << "Impossible";

    return 0;
}
1168 大整数加法
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void init(int a[]) {
    string s;
    cin >> s;

    a[0] = s.size();
    for (int i = 1; i <= a[0]; i ++ ) {
        a[i] = s[a[0]-i] - '0';
    }
}

void dy(int a[]) {
    for (int i = a[0]; i >= 1; i --) {
        cout << a[i];
    }

    cout << endl;
}

//高精度 a + 高精度 b = 高精度 c
void add(int a[], int b[], int c[]) {
    int t = 0;
    c[0] = max(a[0], b[0]);

    for (int i = 1; i <= c[0]; i ++ ) {
        t += a[i] + b[i];
        c[i] = t % 10;
        t /= 10;
    }

    if (t) c[++c[0]] = t;
    while (!c[c[0]] && c[0] > 1) c[0] -- ;
}

int main() {
    init(a);
    init(b);

    add(a, b, c);

    dy(c);

    return 0;
}
1169 大整数减法
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void init(int a[]) {
    string s;
    cin >> s;

    a[0] = s.size();
    for (int i = 1; i <= a[0]; i ++ ) {
        a[i] = s[a[0]-i] - '0';
    }
}

void dy(int a[]) {
    for (int i = a[0]; i >= 1; i --) {
        cout << a[i];
    }

    cout << endl;
}

//高精度 a - 高精度 b = 高精度 c
void sub(int a[], int b[], int c[]) {
    int t = 0;
    c[0] = a[0];

    for (int i = 1; i <= c[0]; i ++ ) {
        t = a[i] - b[i] - t;
        c[i] = (t + 10) % 10;
        t = t < 0 ? 1 : 0;
    }
    while (!c[c[0]] && c[0] > 1) c[0] -- ;
}

int main() {
    init(a);
    init(b);

    sub(a, b, c);

    dy(c);

    return 0;
}
1170 计算2的n次方
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void dy(int a[]) {
    for (int i = a[0]; i >= 1; i --) {
        cout << a[i];
    }

    cout << endl;
}

//高精度 a * 低精度 x = 高精度 c
void mul(int a[], int x, int c[]) {
    int t = 0;
    c[0] = a[0];

    for (int i = 1; i <= c[0]; i ++ ) {
        t += a[i] * x;
        c[i] = t % 10;
        t /= 10;
    }

    while (t) c[++c[0]] = t % 10, t /= 10;
    while (!c[c[0]] && c[0] > 1) c[0] -- ;
}

int main() {
    a[0] = 1, a[1] = 1;

    int n;
    cin >> n;

    while (n--)    {
        mul(a, 2, a);
    }

    dy(a);

    return 0;
}
1171 大整数的因子
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void init(int a[]) {
    string s;
    cin >> s;

    a[0] = s.size();
    for (int i = 1; i <= a[0]; i ++ ) {
        a[i] = s[a[0]-i] - '0';
    }
}

//高精度 a / 低精度 x = 高精度 c,余数为 r
void div(int a[], int x, int c[], int &r) {
    r = 0;
    c[0] = a[0];

    for (int i = c[0]; i >= 1; i -- ) {
        r = r * 10 + a[i];
        c[i] = r / x;
        r %= x;
    }

    while (!c[c[0]] && c[0] > 1)  c[0] -- ;
}

int main() {
    init(a);

    int r;
    bool flag = true;
    for (int i = 2; i <= 9; i ++ ) {
        div(a, i, c, r);
        if (!r) {
            cout << i << ' ';
            flag = false;
        }
    }

    if (flag)  cout << "none";

    return 0;
}
1172 求10000以内n的阶乘
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void dy(int a[]) {
    for (int i = a[0]; i >= 1; i --) {
        cout << a[i];
    }

    cout << endl;
}

//高精度 a * 低精度 x = 高精度 c
void mul(int a[], int x, int c[]) {
    int t = 0;
    c[0] = a[0];

    for (int i = 1; i <= c[0]; i ++ ) {
        t += a[i] * x;
        c[i] = t % 10;
        t /= 10;
    }

    while (t) c[++c[0]] = t % 10, t /= 10;
    while (!c[c[0]] && c[0] > 1) c[0] -- ;
}

int main() {
    a[0] = 1, a[1] = 1;

    int n;
    cin >> n;

    for (int i = 1; i <= n; i ++ ) {
        mul(a, i, a);
    }

    dy(a);

    return 0;
}
1173 阶乘和
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void dy(int a[]) {
    for (int i = a[0]; i >= 1; i --) {
        cout << a[i];
    }

    cout << endl;
}

//高精度 a + 高精度 b = 高精度 c
void add(int a[], int b[], int c[]) {
    int t = 0;
    c[0] = max(a[0], b[0]);

    for (int i = 1; i <= c[0]; i ++ ) {
        t += a[i] + b[i];
        c[i] = t % 10;
        t /= 10;
    }

    if (t) c[++c[0]] = t;
    while (!c[c[0]] && c[0] > 1) c[0] -- ;
}

//高精度 a * 低精度 x = 高精度 c
void mul(int a[], int x, int c[]) {
    int t = 0;
    c[0] = a[0];

    for (int i = 1; i <= c[0]; i ++ ) {
        t += a[i] * x;
        c[i] = t % 10;
        t /= 10;
    }

    while (t) c[++c[0]] = t % 10, t /= 10;
    while (!c[c[0]] && c[0] > 1) c[0] -- ;
}

int main() {
    a[0] = 1, a[1] = 1;

    int n;
    cin >> n;

    for (int i = 1; i <= n; i ++ ) {
        mul(a, i, a);
        add(c, a, c);
    }

    dy(c);

    return 0;
}
1175 除以13
#include 
using namespace std;

const int N = 1e5 + 10;
int a[N], b[N], c[N], x;

void init(int a[]) {
    string s;
    cin >> s;

    a[0] = s.size();
    for (int i = 1; i <= a[0]; i ++ ) {
        a[i] = s[a[0]-i] - '0';
    }
}

void dy(int a[]) {
    for (int i = a[0]; i >= 1; i --) {
        cout << a[i];
    }

    cout << endl;
}

//高精度 a / 低精度 x = 高精度 c,余数为 r
void div(int a[], int x, int c[], int &r) {
    r = 0;
    c[0] = a[0];

    for (int i = c[0]; i >= 1; i -- ) {
        r = r * 10 + a[i];
        c[i] = r / x;
        r %= x;
    }

    while (!c[c[0]] && c[0] > 1)  c[0] -- ;
}

int main() {
    init(a);

    int r;
    div(a, 13, c, r);

    dy(c);
    cout << r;

    return 0;
}

如果您的孩子四年级及以上,对计算机编程感兴趣,且文化课学有余力,欢迎联系客服(微信号:xiaolan7321),参加信息学的学习。我们是专业的信息学竞赛教练,采用线上小班授课的方式,目标是帮助热爱编程的中小学生,在国内外信息学竞赛中取得优秀成绩。

教学特点:

  • 线上小班授课,打好代码基础。避免大班课堂上学生要么“跟不上”,要么“吃不饱”的问题。

  • 教学经验丰富,熟悉学生的知识结构与学习能力,合理安排进度。

  • 以赛代练,通过考级与比赛,不断提高学生能力。

你可能感兴趣的:(中学生信竞)