您的位置:首页 > 其它

uva 10213 How Many Pieces of Land (欧拉公式计算多面体)

2015-06-03 21:32 435 查看
题意:在一个圆上取n个点,求最多能将圆分为多少块;

思路:欧拉公式计算多面体;

欧拉公式:简单多面体的顶点数V、面数F及棱数E之间的关系为V+F-E=2;

首先考虑点数v,有n个在圆上的点,任取一点x,考虑与x相连的每条对角线,假设对角线左边有i个顶点,则右边应有(n-2-i)个顶点,这些顶点相互连接可以产生i*(n-i-2)个顶点,再将所有的x与所有的对角线l求和。每个交点分别算了4次(一个交点由两条线产生,有4个圆上的点会计算到),除以4:

V=n+n/4*(西格玛i=1到n-3) i*(n-i-2);

然后考虑边数E,有n条边在圆上(圆弧),有n条边为相邻两点所形成,上面并没有交点,对于其他的边,若该边上有 i*(n-i-2) 个交点,则其被划分成 i*(n-i-2)+1条线段,而每条这样的线段在求和中会被原对角线的两个交点各算一次,所以还要除以2,:

E=2*n+n/2*(西格玛i=1到n-3)[i*(n-i-2)+1];

使用平方和公式将上面两个式子代入欧拉公式,然后扣除最外层无限大的那个面,可得:

F=(n^4-6*n^3+23*n^2-18*n)/24+1;

F可能超出任何整数类型允许的范围,需要采用高精度运算。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long int64;
int64 m=1e8;
struct Bigint{
int64 s[50];
int l;
void print(){           //输出
printf("%lld",s[l]);
for(int i=l-1;i>=0;i--) printf("%08lld",s[i]);
}
void read(int64 x){     //转为整数数组
l=-1;
memset(s,0,sizeof(s));
do{
s[++l]=x%m;
x/=m;
}while(x);
}
}ans,tmp,t2;
Bigint operator +(Bigint a,Bigint b){  //大数相加
int64 d=0;
a.l=max(a.l,b.l);
for(int i=0;i<=a.l;i++){
a.s[i]+=d+b.s[i];
d=a.s[i]/m;
a.s[i]%=m;
}
if(d) a.s[++a.l]=d;
return a;
}
Bigint operator -(Bigint a,Bigint b){   //大数相减
int64 d=0;
for(int i=0;i<=a.l;i++){
a.s[i]-=d;
if(a.s[i]<b.s[i]) a.s[i]+=m,d=1;
else d=0;
a.s[i]-=b.s[i];
}
while(a.l&&!a.s[a.l]) a.l--;
return a;
}
Bigint operator *(int b,Bigint a){     //小数乘大数
int64 d=0;
for(int i=0;i<=a.l;i++){
d+=a.s[i]*b;
a.s[i]=d%m;
d/=m;
}
while(d){
a.s[++a.l]=d%m;
d/=m;
}
return a;
}
Bigint operator /(Bigint a,int b){       //大数除小数
int64 d=0;
for(int i=a.l;i>=0;i--){
d*=m;
d+=a.s[i];
a.s[i]=d/b;
d%=b;
}
while(a.l&&!a.s[a.l]) a.l--;
return a;
}
Bigint operator *(Bigint a,Bigint b){   //大数相乘
Bigint c;
memset(c.s,0,sizeof(c.s));
for(int i=0;i<=a.l;i++){
for(int j=0;j<=b.l;j++){
c.s[i+j]+=a.s[i]*b.s[j];
if(c.s[i+j]>m){
c.s[i+j+1]+=c.s[i+j]/m;
c.s[i+j]%=m;
}
}
}
c.l=a.l+b.l+10;
while(!c.s[c.l]&&c.l) c.l--;
while(c.s[c.l]>m){
c.s[c.l+1]+=c.s[c.l]/m;
c.s[c.l++]%=m;
}
return c;
}
int v;
void work(){
ans.read(v);
tmp.read(24);//将24转化为整数数组
ans=ans*ans*ans*ans+23*(ans*ans)+tmp-6*(ans*ans*ans)-18*ans;
ans=ans/24;
ans.print();
printf("\n");
}
int main(){
int cas;
scanf("%d",&cas);
while(cas--){
scanf("%d",&v);
work();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: