这里是
题目的大意是比较好懂的,就是说给你一个(N + 1)个N维空间上的点,让你求这个(N + 1)个点的圆心坐标。
拿到这道题目我首先想到的是。。。
为什么? 不为什么
但是感觉这个正确率可能出现问题,因为这个题并不是求极值,所以只能通过其它的方法来判断是否最优(比如说算标准差什么的,但是这样子真的不太靠谱)
又想到了我之前写过一道模拟退火的题目,调了emmm20次吧,于是就没敢写。
这道题目里有一个性质——即圆心的性质
圆心到每一个点的距离都相同,于是我们可以这样子假设
假设答案为(x1,x2,x3,……,xn),当前这个点为(a1,a2,a3……,an),下一点为(b1,b2,b3……,bn)
我们可以列出方程
(a1 - x1) ^ 2 + (a2 - x2) ^ 2 + (a3 - x3) ^ 2 +……+(an - xn) ^ 2 = (b1 - x1) ^ 2 + (b2 - x2) ^ 2 + …… + (an - xn) ^ 2
化简可得
2(a1 - b1) x1 + 2 (a2 - b2)x2 + …… +2(an - bn)xn=a1 ^ 2 + a2 ^ 2 +……+an ^ 2 - b1 ^ 2 - b2 ^ 2 - …… - bn ^ 2
我们一共有N + 1个点
所以我们可以列出N个方程
接下来就使用
把所有的未知数解出来,由于数据保证有解,所以不会存在自由元
大家可以大胆地去做啦
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #define ll long long 8 #define db double 9 #define fo(i,x,y) for (int i=x; i<=y; i++)10 #define pr(i,x,y) for (int i=x; i>=y; i--)11 #define cl(a,x) memset(a,x,sizeof(a))12 13 using namespace std;14 15 int N;16 db Mat[15][15];17 db a[15][15];18 19 int main()20 {21 scanf("%d",&N);22 cl(Mat,0);23 fo(i,1,N + 1)24 {25 fo(j,1,N)26 {27 scanf("%lf",&a[i][j]);28 if (i != 1)29 {30 Mat[i - 1][j]=2 * (a[i][j] - a[i - 1][j]);31 Mat[i - 1][N + 1]+=a[i][j] * a[i][j] - a[i - 1][j] * a[i - 1][j];32 }33 }34 }35 fo(i,1,N)36 {37 int T=i;38 fo(j,i + 1,N)39 {40 if (fabs(Mat[j][i]) > fabs(Mat[T][i]))41 {42 T=j;43 }44 }45 if (T != i)46 {47 fo(j,1,N + 1)48 {49 swap(Mat[i][j],Mat[T][j]);50 }51 }52 fo(j,i + 1,N)53 {54 db X=Mat[j][i] / Mat[i][i];55 fo(k,i,N + 1)56 {57 Mat[j][k]-=Mat[i][k] * X;58 }59 }60 }61 pr(i,N,1)62 {63 fo(j,i + 1,N)64 {65 Mat[i][N + 1]-=Mat[j][N + 1] * Mat[i][j];66 }67 Mat[i][N + 1]/=Mat[i][i];68 }69 fo(i,1,N - 1)70 {71 printf("%.3f ",Mat[i][N + 1]);72 }73 printf("%.3f\n",Mat[N][N + 1]);74 return 0;75 }