1 条题解
-
0
题解
在 维空间里给出 个点,它们一定满足一条线性关系,因此凸包只可能是“两个 维单纯形共用同一个底面”的形状。若把所有点都投影到同一个基准点 ,那么以其它 个点与 的向量作为行向量组成的 行列式的绝对值,恰好就是这 个点构成的单纯形的体积乘以 。
令其中任意一个点为“被删除的点”。对每个删除的点,把剩下的 个点拿出来,用第一个点作为基准,写出 个向量并计算行列式(用高斯消元即可)。把所有删除点得到的行列式绝对值加起来,就等于两个单纯形体积和的两倍。最后除以 ,并对 取模,即为答案。
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<bitset> #include<queue> #include<ctime> #include<cmath> #include<set> #include<map> #define infile(filename) freopen(filename".in","r",stdin) #define outfile(filename) freopen(filename".out","w",stdout) #define usefile(filename) infile(filename),outfile(filename) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef __int128 I; namespace IO { const int BUF=1<<20; static char ch[BUF]={},out[BUF]={},*l=ch,*r=ch,*o=out; #define FASTIO #ifdef FASTIO inline char gc() { return (l==r&&(r=(l=ch)+fread(ch,1,BUF,stdin),l==r))?EOF:*l++; } #else inline char gc() { return getchar(); } #endif inline void flush() { fwrite(out,1,o-out,stdout),o=out; } inline void putc(char ch) { if(o==out+BUF) flush(); *o++=ch; } struct flusher{~flusher(){flush();}}_; }; using IO::gc; using IO::putc; template <typename T> void read(T &a) { static char fushu,ch; a=fushu=0; do ch=gc(); while(ch!='-'&&(ch<48||ch>57)); if(ch=='-') ch=gc(),fushu=1; do a=(a<<1)+(a<<3)+(ch^48),ch=gc(); while(ch>47&&ch<58); if(fushu) a=-a; } template <typename T,typename ...Args> void read(T &a,Args &...args) { read(a),read(args...); } template <typename T> void write(T a) { static char que[114]={},*p=que; if(!a) putc(48); if(a<0) putc('-'),a=-a; while(a) *p++=(a%10)^48,a/=10; while(p!=que) putc(*--p); putc(32); } template <typename T,typename ...Args> void write(T a,Args ...args) { write(a),write(args...); } template <typename T> void ckmax(T &a,T b) { if(a<b) a=b; } template <typename T> void ckmin(T &a,T b) { if(b<a) a=b; } const int N=40; const double eps=1e-6; int T,n,p[N][N]={}; double a[N][N]={}; double det(int n) { int i,j,k; double muler,ans=1; for(i=1;i<=n;++i) { for(j=i+1,k=i;j<=n;++j) if(fabs(a[j][i])>fabs(a[k][i])) k=j; swap(a[i],a[k]); if(fabs(a[i][i])<eps) return 0; ans*=a[i][i]; for(j=i+1;j<=n;++j) if(fabs(a[j][i])>eps) { muler=a[j][i]/a[i][i]; for(k=i;k<=n;++k) a[j][k]-=a[i][k]*muler; } } return ans; } int main() { // usefile("atmo"); int i,j,k,tot,fir; double ans=0; read(T); loop : --T; read(n); for(i=1;i<=n+1;++i) for(j=1;j<n;++j) read(p[i][j]); for(i=1,ans=0;i<=n+1;++i) { for(j=1,tot=0;j<=n+1;++j) if(i!=j) { if(!tot) fir=j; for(k=1;k<n;++k) a[tot][k]=p[j][k]-p[fir][k]; ++tot; } ans+=fabs(round(det(n-1))); } ans/=2.0; printf("%lld\n",ll(round(ans))%1000000007ll); if(T) goto loop; return 0; }
- 1
信息
- ID
- 5472
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者