题目大意

  有 \(n\) 个 \(n\) 维空间中的球,求这些球的所有公切面。

  保证不会无解或有无穷多组解。

  \(n\leq 10\)

题解

  你可以认为这是一道传统题。

  记公切面为 \(a_1x_1+a_2x_2+\cdots+ a_nx_n=d\),满足 \(\sum_ia_i^2=1\)。

  一个点 \(x_1,x_2,\ldots,x_n\) 到这个面的距离为

\[\frac{\lvert a_1x_1+a_2x_2\cdots +a_nx_n-d\rvert}{\sqrt{a_1^2+a_2^2+\cdots+a_n^2}}
\]

  对于第 \(i\) 个球,有 \(\lvert\sum_{j}a_jx_{i,j}-d\rvert=r\)。

  枚举所有 \(\lvert\sum_{j}a_jx_{i,j}-d\rvert\) 的符号,把绝对值符号去掉。

  然后解方程解出 \(a_i=D_1d+D_2\),带进 \(\sum_ia_i^2=1\) 中解方程就可以解出 \(d\)。

  时间复杂度:\(O(n^32^n)\)。

  直接解方程可能会有奇怪情况,所以要把所有坐标偏移一个值。

代码

const ldb eps=1e-6;
ldb DELTA[]={0,0.235,0.3746,0.1246,0.2153,0.364,0.1253,0.6124,0.164,0.7543,0.35476};
int n;
ldb a[20][20];
ldb r[20];
ldb ans[2100][20][20];
ldb b[20][20];
ldb c[20][20];
ldb e[20];
int cnt;
void gao(ldb d)
{
for(int i=1;i<=n;i++)
e[i]=c[i][n+1]*d+c[i][n+2];
cnt++;
for(int i=1;i<=n;i++)
{
ldb s=0;
for(int j=1;j<=n;j++)
s+=a[i][j]*e[j];
s-=d;
for(int j=1;j<=n;j++)
ans[cnt][i][j]=a[i][j]-s*e[j];
}
}
void calc()
{
memcpy(c,b,sizeof b);
int flag=0;
for(int i=1;i<=n;i++)
{
int x=i;
for(int j=i;j<=n;j++)
if(fabs(c[j][i])>fabs(c[x][i]))
x=j;
if(fabs(c[x][i])<eps)
{
flag=1;
continue;
}
if(x!=i)
swap(c[x],c[i]);
ldb v=1/c[i][i];
for(int j=1;j<=n+2;j++)
c[i][j]*=v;
for(int j=1;j<=n;j++)
if(j!=i)
{
ldb v=c[j][i];
for(int k=1;k<=n+2;k++)
c[j][k]-=c[i][k]*v;
}
}
if(flag)
{
// ldb d;
// for(int i=1;i<=n;i++)
// if(!c[i][i])
// {
// if(flag)
// {
// }
// else
// {
// }
printf("error\n");
return;
}
ldb A=0,B=0,C=0;
for(int i=1;i<=n;i++)
{
A+=c[i][n+1]*c[i][n+1];
B+=2*c[i][n+1]*c[i][n+2];
C+=c[i][n+2]*c[i][n+2];
}
C-=1;
if(fabs(A)<eps)
{
if(fabs(B)<eps)
{
return;
}
ldb d=-C/B;
gao(d);
}
else
{
ldb delta=B*B-4*A*C;
if(delta<-eps)
return;
else
delta=max(delta,(ldb)0);
if(delta<eps)
{
ldb d=-B/(2*A);
gao(d);
}
else
{
ldb d1=(-B+sqrt(delta))/(2*A);
gao(d1);
ldb d2=(-B+sqrt(delta))/(2*A);
gao(d2);
}
}
}
void dfs(int x)
{
if(x>n)
{
calc();
return;
}
for(int i=1;i<=n;i++)
b[x][i]=a[x][i];
b[x][n+1]=1;
b[x][n+2]=r[x];
dfs(x+1);
if(fabs(r[x])<eps)
return;
b[x][n+2]=-r[x];
dfs(x+1);
}
void solve()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%Lf",&a[i][j]);
a[i][j]-=DELTA[j];
}
scanf("%Lf",&r[i]);
}
cnt=0;
dfs(1);
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++)
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
printf("%.20Lf ",ans[i][j][k]+DELTA[k]);
printf("\n");
}
}
int main()
{
// freopen("0.in","r",stdin);
int t;
scanf("%d",&t);
while(t--)
solve();
return 0;
}

【THUSC2017】【LOJ2982】宇宙广播 计算几何 高斯消元的更多相关文章

  1. 【THUSC2017】【LOJ2978】杜老师 高斯消元

    题目大意 给你 \(l,r\),求从 \(l\) 到 \(r\) 这 \(r-l+1\) 个数中能选出多少个不同的子集,满足子集中所有的数的乘积是一个完全平方数. 对 \(998244353\) 取模 ...

  2. 【BZOJ-3143】游走 高斯消元 + 概率期望

    3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2264  Solved: 987[Submit][Status] ...

  3. 【BZOJ-3270】博物馆 高斯消元 + 概率期望

    3270: 博物馆 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 292  Solved: 158[Submit][Status][Discuss] ...

  4. *POJ 1222 高斯消元

    EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9612   Accepted: 62 ...

  5. [bzoj1013][JSOI2008][球形空间产生器sphere] (高斯消元)

    Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧 ...

  6. hihoCoder 1196 高斯消元·二

    Description 一个黑白网格,点一次会改变这个以及与其连通的其他方格的颜色,求最少点击次数使得所有全部变成黑色. Sol 高斯消元解异或方程组. 先建立一个方程组. \(x_i\) 表示这个点 ...

  7. BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基

    [题目分析] 高斯消元求线性基. 题目本身不难,但是两种维护线性基的方法引起了我的思考. void gauss(){ k=n; F(i,1,n){ F(j,i+1,n) if (a[j]>a[i ...

  8. SPOJ HIGH Highways ——Matrix-Tree定理 高斯消元

    [题目分析] Matrix-Tree定理+高斯消元 求矩阵行列式的值,就可以得到生成树的个数. 至于证明,可以去看Vflea King(炸树狂魔)的博客 [代码] #include <cmath ...

  9. UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

随机推荐

  1. .NET开发中基础问题,CODE First AND DB First(大牛自动忽略,小白可以看一下)

    最近在做一个新项目开发时,碰到了下面这个问题.在使用EF时,提示错误信息 To continue using Database First or Model First ensure that the ...

  2. 六大设计原则(四)ISP接口隔离原则(上)

    ISP的定义 首先明确接口定义 实例接口 我们在Java中,一个类用New关键字来创建一个实例.抛开Java语言我们其实也可以称为接口.假设Person zhangsan = new Person() ...

  3. Web前端 前端相关书籍推荐

    一.HTML篇 1)<精通HTML> 2)<HTML5秘籍> 3)<HTML5权威指南> 4)<Head First HTML5 Programming(中文 ...

  4. 自定义编译gdal库

    作者:朱金灿 来源:http://blog.csdn.net/clever101 使用下载下来的gdal库的makefile来编译gdal库,生成的gdal库的名字debug版本和release版本都 ...

  5. promise原理

      简介 Promise 对象用于延迟(deferred) 计算和异步(asynchronous )计算.一个Promise对象代表着一个还未完成,但预期将来会完成的操作.Promise 对象是一个返 ...

  6. C,java,Python,这些名字背后的江湖!

    还记得高中的时候,有一次我们计算机老师问我们班要不要去参加市里面的C语言比赛,当时还小的我对编程世界压根就一片空白.那时候我就想啊,为什么是C语言,那么A语言,B语言或者是D语言又是什么呢? 后来就到 ...

  7. SQL 知道字段名 全表搜索此字段属于哪个表

    SELECT name FROM sysobjects WHERE id IN (SELECT ID FROM syscolumns WHERE name='字段名')

  8. 猴子选大王 (约瑟夫环)(c#)

    猴子选大王问题: 一堆猴子都有编号,编号是1,2,3 ...m ,这群猴子(m个)按照1到m的顺序围坐一圈, 从第1开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子, ...

  9. 使用Log4Net进行错误日志记录

    http://blog.csdn.net/zdw_wym/article/details/48802821

  10. Redis与Memocache的区别

    转载地址:http://gnucto.blog.51cto.com/3391516/998509 Redis与Memcached的区别 传统MySQL+ Memcached架构遇到的问题 实际MySQ ...