球形空间产生器[JSOI2008]
题目链接:https://www.luogu.org/problemnew/show/P4035
题解:
明显是高斯消元题。问题是距离相等的条件怎么用呢?
距离相等的条件可以列出n个等式(即(x-xi)^2+(y-yi)^2 == (x-xi+1)^2+(y-yi+1)^2 ,[以平面坐标系为例]),整理得2*(xi+yi-xi+1-yi+1)== xi^2+yi^2-xi+1^2-yi+1^2
通过解n元方程组,求得的解即为坐标。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define LL long long 7 #define RI register int 8 #define eps 1e-7 9 using namespace std; 10 const int INF = 0x7ffffff ; 11 const int N = 10 + 2 ; 12 13 inline int read() { 14 int k = 0 , f = 1 ; char c = getchar() ; 15 for( ; !isdigit(c) ; c = getchar()) 16 if(c == '-') f = -1 ; 17 for( ; isdigit(c) ; c = getchar()) 18 k = k*10 + c-'0' ; 19 return k*f ; 20 } 21 int n ; double pre[N], now[N], hh[N][N+1] ; 22 23 inline bool guass() { 24 for(int i=0;i<n;i++) { 25 int r = i ; 26 for(int j=i+1;j<n;j++) if(hh[j][i] > hh[r][i]) r = j ; 27 if(r != i) for(int j=i;j<=n;j++) swap(hh[i][j],hh[r][j]) ; 28 if(fabs(hh[r][i]) < eps) return 0 ; // 其实这一行不用写(因为数据保证有解),但写板子题还是要养成好习惯写得完整一些qaq 29 for(int j=i+1;j<n;j++) { 30 double f = hh[j][i]/hh[i][i] ; 31 for(int k=i;k<=n;k++) { 32 hh[j][k] -= hh[i][k]*f ; 33 } 34 } 35 } 36 for(int i=n-1;i>=0;i--) { 37 for(int j=i+1;j<n;j++) hh[i][n] -= hh[i][j]*hh[j][n] ; 38 hh[i][n] /= hh[i][i] ; 39 } 40 return 1 ; 41 } 42 43 inline double sqr(double x) { return x*x ; } 44 int main() { 45 n = read() ; 46 for(int i=0;i<n;i++) scanf("%lf",&pre[i]) ; 47 for(int i=0;i<n;i++) { 48 hh[i][n] = 0 ; 49 for(int j=0;j<n;j++) { 50 scanf("%lf",&now[j]) ; 51 hh[i][j] = (now[j]-pre[j])*2 ; 52 hh[i][n] += sqr(now[j])-sqr(pre[j]) ; 53 pre[j] = now[j] ; 54 } 55 56 } 57 /* 调试用 58 for(int i=0;i<n;i++) { 59 for(int j=0;j<=n;j++) printf("%lf ",hh[i][j]) ; 60 printf("\n") ; 61 } 62 */ 63 guass() ; // 数据保证有解,所以无需判断 64 for(int i=0;i<n;i++) { 65 printf("%.3lf ",hh[i][n]) ; 66 } 67 return 0 ; 68 }