题意:在一个圆上取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; }
时间: 2024-12-25 15:26:56