您的位置:首页 > 其它

UVA 10519 !! Really Strange !!

2013-10-31 00:21 302 查看
题意:n个圆两两相交,将平面分成了几部分,假设已有n-1个圆,那么第n个圆将与前n-1个圆相交2*(n-1)个点,也就是2*(n-1)个弧,而一个弧将产生出一个新的部分,所以:

f(n) = f(n-1) + 2*(n-1),推出公式:f(n) = n^2-n+2,大数,害我错了好几次的是:n=0时的特判

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 1000000;

char n[MAXN];
long long p[MAXN],ans[MAXN];
 // f(n) = n^2-n+2
 // f(0) = 1
void pow_big(long long *a,long long *b,int &len){
    int i,j;
    for (i = 0; i < len; i++)
        for (j = 0; j < len; j++)
            ans[i+j] += a[i] * b[j];
    len *= 2;
    for (i = 0; i < len; i++){
        ans[i+1] += ans[i] / 10;
        ans[i] %= 10;
    }
    while (ans[len] == 0)
        len--;
    len++;
}

void cal(long long *b,int &len){
    int i,c=0;
    ans[0] += 2;
    if (ans[0] >= 10){
        ans[1] += ans[0] / 10;
        ans[0] %= 10;
    }
    for (i = 0; i < len; i++){
        ans[i] = ans[i] - b[i] + c;
        if (ans[i] < 0){
            ans[i] += 10;
            c = -1;
        }
        else c = 0;
    } 
    while (ans[len-1] == 0)
        len--;
}

int main(){
    while (scanf("%s",n) != EOF){
        memset(p,0,sizeof(p));
        memset(ans,0,sizeof(ans));
        int len = strlen(n);
        for (int i = 0; i < len; i++)
            p[i] = n[len-1-i] - '0';
        if (p[0] == 0){
            printf("1\n");
            continue;
        }
        pow_big(p,p,len);
        cal(p,len);
        for (int i = len-1; i >= 0; i--)
            printf("%lld",ans[i]);
        printf("\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: