高斯消元:d[i]-1/2d[i-1]-1/2d[i+1]=1;
规律:d[3]=n-1+n-3+n-5 d[2]=n-1+n-3 d[1]=n-1
#include <bits/stdc++.h> using namespace std; const int MAXN=1005; double a[MAXN][MAXN];//增广矩阵 double x[MAXN];//解集 bool free_x[MAXN];//标记是否是不确定的变元 // 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解,但无整数解, //-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数) //有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var. int Gauss(int equ,int var,int MOD) { int i,j,k; int max_r;// 当前这列绝对值最大的行. int col;//当前处理的列 double ta,tb; double LCM; double temp; for(int i=0;i<=var;i++) { x[i]=0; free_x[i]=true; } //转换为阶梯阵. col=0; // 当前处理的列 for(k = 0;k < equ && col < var;k++,col++) {// 枚举当前处理的行. // 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差) max_r=k; for(i=k+1;i<equ;i++) { if(abs(a[i][col])>abs(a[max_r][col])) max_r=i; } if(max_r!=k) {// 与第k行交换. for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]); } if(a[k][col]==0) {// 说明该col列第k行以下全是0了,则处理当前行的下一列. k--; continue; } for(i=k+1;i<equ;i++) {// 枚举要删去的行. if(a[i][col]!=0) { LCM = abs(a[i][col])*abs(a[k][col]); ta = LCM/abs(a[i][col]); tb = LCM/abs(a[k][col]); if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加 for(j=col;j<var+1;j++) { a[i][j] = a[i][j]*ta-a[k][j]*tb; } } } } // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵. // 计算出Xn-1, Xn-2 ... X0. for (i = var - 1; i >= 0; i--) { temp = a[i][var]; for (j = i + 1; j < var; j++) { if (a[i][j] != 0) temp -= a[i][j] * x[j]; } x[i] =temp / a[i][i] ; } return 0; } int main() { int t,y,n; scanf("%d",&t); while(t--) { memset(a,0,sizeof(a)); scanf("%d%d",&n,&y); a[0][0]=1; for(int i=1;i<n;i++) { a[i][i-1]=-0.5; a[i][(i+1)%n]=-0.5; a[i][n]=1; a[i][i]=1; } Gauss(n,n,100000); printf("%.4f\n",x[y]); } return 0; }