zoukankan      html  css  js  c++  java
  • 高斯消元 zoj 3645 poj 1222/XOR消元

    double  a[maxn][maxn] , x[maxn] ;  //a[i][j] 系数矩阵 , a[i][n+1]  = y[i] , x解
    int     n ;   //n个方程
    void    guass(){
            int i , j , k ;
            double  sum , rate ;
            for(k = 1 ; k < n ;  k++){
                 for(i = j = k ; i <= n ; i++) j = fabs(a[i][k]) > fabs(a[j][k]) ? i : j ;
                 for(i = k ; i <= n+1 ; i++)  swap(a[j][i] , a[k][i]) ;
                 for(i = k+1 ; i <= n ; i++)
                     for(rate = a[i][k]/a[k][k] , j = k ; j <= n+1 ; j++)
                          a[i][j] -= a[k][j]*rate ;
            }
            for(i = n ; i >= 1 ; i--){
                for(sum = 0 , j = i+1 ; j <= n ; sum += a[i][j]*x[j],j++) ;
                x[i] = (a[i][n+1] - sum)/a[i][i] ;
            }
    }
    
    double  Fix(double x){   // 将 -0.000 变成 0.00 ,结果输出Fix(x[])
            if(fabs(x) < 1e-4) return 0 ;
            return x ;
    }

    另一个版本的高斯消元

    double  a[Max_N][Max_N], x[Max_N],b[Max_N][Max_N]; // 系数矩阵,double型
    void guass(int n){
        int i,j,k;// 这里 i表示行,j表示列,k表示某行的某列(确定一个元素)
        for(i=0; i<n; i++)
            for(j=0; j<n; j++)
                b[i][j]=a[i][j];
        for(i=0; i<n; i++)
            b[i][n] = x[i];
        for(j=0; j<n; j++){
            for(k=i=j; i<n; i++) k = fabs(b[i][j]) > fabs(b[k][j]) ? i : k ;
            for(i=0; i<=n; i++)  swap(b[j][i],b[k][i]);
            //把正在处理的那一行的对角线上的系数变成1,同一行除b[j][j],该位置的系数不处理
            for(i=j+1 ; i<=n; i++) b[j][i] /= b[j][j];
            for(i=0; i<n; i++){
                if(i != j)
                    for(k=j+1; k<=n; k++) b[i][k] -= b[i][j]*b[j][k]; // 做行变换,被消的同一列系数不处理
            }
        }
    }

    zoj 3645 BiliBili

    题目来源:   http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4835

    题目意思很明显

    给你一个方程组 让你求(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11)

    但是方程组的形式是一个二次方程组

    (ai1-x1)^2 + (ai2-x2)^2 +(ai3-x1)^2 + (ai4-x2)^2 +(ai5-x1)^2 + (ai6-x2)^2 +(ai7-x1)^2 + (ai8-x2)^2 + (ai9-x2)^2 +(ai10-x1)^2 + (ai11-x2)^2  = dis ^2

    于是我们可以发现 用两个方程相减就可以得到一个一次方程组。 这样操作11次得到一个新的方程组,然后用高斯消元法求解即可。

    代码如下:

    using namespace std ;
    const double pi= acos(-1);
    #define arc(x) (x / 180 * pi)
    typedef long long LL ;
    const double EPS = 1e-8;
    const int Max_N = 15;
    double  a[Max_N][Max_N], d[Max_N],b[Max_N][Max_N]; // 系数矩阵,double型
    int n; // 方程的个数
    void guass(){
        int i,j,k;
        for(j=0; j<n; j++){
            for(k=i=j; i<n; i++) k = fabs(b[i][j]) > fabs(b[k][j]) ? i : k ;
            for(i=0; i<=n; i++)  swap(b[j][i],b[k][i]);
    
            for(i=j+1 ; i<=n; i++) b[j][i] /= b[j][j];
            for(i=0; i<n; i++){
                if(i != j)
                    for(k=j+1; k<=n; k++) b[i][k] -= b[i][j]*b[j][k];
            }
        }
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            n=11;
            for(int i=0; i<=n; i++){
                for(int j=0; j<n; j++)
                    scanf("%lf",&a[i][j]);
                scanf("%lf",&d[i]);
            }
            memset(b,0,sizeof(b));
            for(int i=1; i<=n; i++){
                for(int j=0; j<n; j++){
                    b[i-1][j] = 2*(a[i][j] - a[i-1][j] );
                    b[i-1][n] += a[i][j]*a[i][j] - a[i-1][j]*a[i-1][j];
                }
            }
            for(int i=0; i<n; i++) b[i][n] += d[i]*d[i] - d[i+1]*d[i+1];
            guass();
            for(int i=0; i<n-1; i++)
                printf("%.2lf ",b[i][n] + EPS);  // 输出时注意这里的判断, 处理-0.0000
            printf("%.2lf
    ",b[n-1][n] + EPS);
        }
        return 0;
    }

     poj 1222 EXTENDED LIGHTS OUT

    题目来源:    http://poj.org/problem?id=1222

    分析:转化为横坐标为灯(灯0,灯1,。。。,灯29)纵坐标为开关(开关0,开关1,。。。,开关29),记为矩阵A,矩阵A与灯的初始状态无关,A(i,j)=1表示开关j对灯i有影设矩阵X,X是30*1的矩阵,表示开关是否需要打开。X(i,0)=1表示开关i需要打开。矩阵X是待求的。设矩阵B 30*1,表示结果。B只与灯的初始状态有关,初始时灯i是开着的,则B(i,0)=1。解方程AX=B。

    代码如下:

    const int Max_N = 35;
    int a[Max_N][Max_N]; // 系数矩阵,double型,AX = Y
    int n; // 方程的个数 a[i][n]存储的是Y向量
    void guass(){
        int i,j,k; // i表示行,j表示列
        for(i=0; i<n; i++){
            for(k=i; k<n; k++) //寻找不为零的 a[i][i],通过交换
                if(a[k][i]) break;
            for(j=0; j<=n; j++) swap(a[k][j], a[i][j]);
            for(j=0; j<n; j++)
                if(i != j && a[j][i]) // 如果a[j][i] == 0 ,则该行不需要变换
                    for(k=0; k<=n; k++)
                        a[j][k] ^= a[i][k];
        }
    }
    int main(){
        int t,u=1;
        scanf("%d",&t);
        while(t--){
            int i,j;
            n=30;
            memset(a,0,sizeof(a));
            for(i=0; i<n; i++)
                scanf("%d",&a[i][n]); // Y value
            for(i=0; i<n; i++){
                a[i][i]=1;
                if(i>5) a[i][i-6] = 1 ;// up a[i][j] 表示第i个灯被第j个开关影响
                if(i<24) a[i][i+6] =1 ; // down
                if(i%6) a[i][i-1] = 1 ; // left
                if(i%6 != 5) a[i][i+1] = 1 ; //right
            }
            guass();
            printf("PUZZLE #%d
    ",u++);
            for(i=0; i<n; i++){
                if(i%6 != 5)
                    printf("%d ",a[i][n]);
                else
                    printf("%d
    ",a[i][n]);
            }
        }
        return 0;
    }
  • 相关阅读:
    敏捷个人手机应用:如何下载敏捷个人资料
    2014年8月10日:敏捷个人奥森跑步+慢走分享
    敏捷个人手机应用:如何进行敏捷个人练习
    敏捷个人新体系:定位
    任何社区,只要能影响他人成长的人,都可以成为敏捷个人的荣誉会员
    亲密爱人:《亲密关系》读书笔记
    亲密爱人:《亲密关系
    2014.7.12 敏捷个人奥森健步走&敏友分享会.活动报道
    开放产品开发(OPD):产品负责人的工作原则和方法
    #敏捷个人资料# 免费下载 《敏捷个人-认识自我,管理自我 v0.8.pdf》
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3682908.html
Copyright © 2011-2022 走看看