1. 程式人生 > >HDU 6222 Heron and His Triangle ( 2017 ICPC瀋陽, 線性遞推 + 大數)

HDU 6222 Heron and His Triangle ( 2017 ICPC瀋陽, 線性遞推 + 大數)

A triangle is a Heron’s triangle if it satisfies that the side lengths of it are consecutive integers t−1, t, t+ 1 and thatits area is an integer. Now, for given n you need to find a Heron’s triangle associated with the smallest t bigger  than or equal to n.

Input

The input contains multiple test cases. The first line of a multiple input is an integer T (1 ≤ T ≤ 30000) followedby T lines. Each line contains an integer N (1 ≤ N ≤ 10^30). 

Output

For each test case, output the smallest t in a line. If the Heron’s triangle required does not exist, output -1.

Sample Input

4
1
2
3
4

Sample Output

4
4
4
4

題意:給你一個 n , 要求你找一個最小 t ,滿足 t >= n 且 t - 1, t, t + 1 為邊長所構成的三角形的面積為整數。

思路:先直接打表出前面幾項 4 14 52 194 724 2702,然後可暴力求線性遞推式係數 推出一個 線性遞推式 a[n] = 4 * a[n-1] - a[n - 2],接著打表就可以了。   不會java大數,我也很難過。QAQ

AC程式碼:

#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define INT(t) int t; scanf("%d",&t)
#define LLI(t) LL t; scanf("%I64d",&t)

using namespace std;

char ans[100][100];
char tmp[100];
char tmp1[100];
char four[10] = {'4', '\0'};

void bigjian(char *a, char *b) {
    int i = strlen(a) - 1, j = strlen(b) - 1;
    int x = 0, c[205] = {0}, flag = 1, d[205] = {0}, f[205] = {0};
    for(int l = 0; l <= i; l++)
        c[l] = a[l] - '0';
    for(int l = 0; l <= j; l++)
        d[l] = b[l] - '0';
    while(j != -1) {
        if(c[i] < d[j]) {
            c[i] += 10;
            c[i - 1] -= 1;
        }
        f[x++] = c[i] - d[j];
        i--;
        j--;
    }
    while(i >= 0) {
        if(c[i] < 0) {
            c[i] += 10;
            c[i - 1] -= 1;
        }
        f[x++] = c[i];
        i--;
    }
    int p = 0;
    if(f[x - 1] == 0)
        flag = 0;
    for(int y = x - 1; y >= 0; y--) {
        if(f[y] != 0)
            flag = 1;
        if(flag == 1)
            tmp[p ++] = f[y] + '0';
    }
    if(flag == 0)
        tmp[p ++] = '0';
    tmp[p] = '\0';
}

void bigx(char *a, char *b) {
    int x, k, lena, lenb, lenb1, c[150] = {0};
    lena = strlen(a) - 1;
    lenb = strlen(b);
    lenb1 = lenb;
    while(lenb--) {
        x = lenb1 - lenb - 1;
        for(int i = lena; i >= 0; i--) {
            k = (a[i] - '0') * (b[lenb] - '0');
            c[x] += k;
            if(c[x] >= 10) {
                c[x + 1] += c[x] / 10;
                c[x] %= 10;
            }
            x++;
        }
    }
    int p = 0;
    if(c[x] != 0)
        tmp1[p ++] = c[x] + '0';
    for(int i = x - 1; i >= 0; i--)
        tmp1[p ++] = c[i] + '0';
    tmp1[p] = '\0';
}

int main() {
    ans[0][0] = '2';
    ans[1][0] = '4';
    int i;
    for(i = 2; i <= 101; i ++) {
        memset(tmp, 0, sizeof(tmp));
        memset(tmp1, 0, sizeof(tmp1));
        bigx(ans[i - 1], four);   /// 存入 tmp1
        bigjian(tmp1, ans[i - 2]); /// 存入 tmp
        if(strlen(tmp) > 31) break;
        strcpy(ans[i], tmp);
    }
    int t; scanf("%d",&t);
    while(t --){
        char n[50]; scanf("%s",n);
        for(int j = 1;j <= i + 1;j ++){
            if(strlen(n) < strlen(ans[j])){
                printf("%s\n",ans[j]);
                break;
            }
            else {
                if(strlen(n) == strlen(ans[j])){
                    if(strcmp(n,ans[j]) <= 0){
                        printf("%s\n",ans[j]);
                        break;
                    }
                }
            }
        }
    }
    return 0;
}