OpenJudge C16D Extracurricular Sports(构造/大数)

来源:互联网 发布:淘宝知识产权扣分 编辑:程序博客网 时间:2024/06/11 14:59

题目链接:
OpenJudge C16D Extracurricular Sports
题意:
构造n个互不相同的数使得这n个数的最小公倍数等于它们之和。2<= n <= 200.如果不存在这样的构造输出-1.
分析:
可以证明2个数的时候不存在这样的构造。当n = 3 时,可以构造出1,2,3。当n = 4时,可以构造出1,4,5,10.
当n>4时,假设前n - 2个数的和是t(最小公倍数也是t),因为n = 3时的合法构造1,2,3,可以令第n - 1个数是2 × t,第n 个数是3×t,这时这n个数的最小公倍数和数字之和都是6*t,因此由n =3 和n =4 的情况,依次往下递推就可以得到答案了。
因为数字比较大,用数组存数字,简单的大数乘法。

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <iostream>#include <climits>#include <iomanip>#include <string>using namespace std;const int MAX_N = 210;const int MAX_M = 1010;int ans[MAX_N][MAX_M], sum[MAX_M], tmp[MAX_N], len;void solve(int n){    memset(ans, 0, sizeof(ans));    int st ;    if(n & 1){        ans[1][0] = 1, ans[2][0] = 2;         ans[3][0] = 3;        len = 1, sum[0] = 6;        st = 5;    }else {        ans[1][0] = 1, ans[2][0] = 4;        ans[3][0] = 5, ans[4][0] = 10;        len = 2;         sum[0] = 0, sum[1] = 2;        st = 6;    }    for(int i = st; i <= n; i += 2){        int carry1 = 0, carry2 = 0, carry3 = 0;        int tmp1 = 0, tmp2 = 0, tmp3 = 0;        for(int j = 0; j < len; j++){            ans[i - 1][j] = sum[j] * 2 + carry1;            carry1 = ans[i - 1][j] / 10;            ans[i - 1][j] %= 10;            ans[i][j] = sum[j] * 3 + carry2;            carry2 = ans[i][j] / 10;            ans[i][j] %= 10;            tmp[j] = sum[j] * 6 + carry3;            carry3 = tmp[j] / 10;            tmp[j] %= 10;        }        if(carry1) ans[i - 1][len] = carry1;        if(carry2) ans[i][len] = carry2;        if(carry3){             tmp[len] = carry3;            len++;        }        for(int j = 0; j < len; j++){            sum[j] = tmp[j];        }       }   }int main(){    ios_base::sync_with_stdio(0);    cin.tie(0);    int T, n;    cin >> T;    while(T-- > 0){        cin >> n;        if(n == 2){            cout << -1 << endl;            continue;        }        solve(n);        for(int i = 1; i <= n; i++){            int ed = MAX_M - 10;            while(ans[i][ed] == 0) ed--;             for(int j = ed; j >= 0; j--){                cout << ans[i][j] ;            }            cout << endl;        }        //cout << "******" << len << "******" << endl;    }    return 0;}
0 0
原创粉丝点击