• 数学 --- 高斯消元 POJ 1830


    开关问题 

    Problem's Link: http://poj.org/problem?id=1830


     

    Mean: 


    analyse:

    增广矩阵:con[i][j]:若操作j,i的状态改变则con[i][j]=1,否则con[i][j]=0。

    最后的增广矩阵应该是N*(N+1),最后一列:对比开光的始末状态,若相同则为0,若不同则为1;

    最后的解共有三种:
    1.无解,既出现了一行中前面N个数为0,第N+1的值非0;
    2.没有第1种情况出现,存在X行数值全为0,则解的个数为2^X;
    3,没有1,2 两种情况出现,唯一解,输出1。

    Time complexity: O(n)

     

    Source code: 

    /*
    * this code is made by crazyacking
    * Verdict: Accepted
    * Submission Date: 2015-06-17-22.36
    * Time: 0MS
    * Memory: 137KB
    */
    #include <queue>
    #include <cstdio>
    #include <set>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <climits>
    #include <map>
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #define  LL long long
    #define  ULL unsigned long long
    using namespace std;
    const int p=30;
    int con[p][p];
    int N;
    int beg[p],fin[p];
    int function()
    {
          int i,j,k,t,row,col,temp,count=0;
          for(row=col=1; row<=N&&col<=N; row++,col++)
          {
                if(con[row][col]==0)
                {
                      for(i=row+1; i<=N; i++)
                      {
                            if(con[i][col]!=0)
                            {
                                  for(j=1; j<=N+1; j++)
                                  {
                                        swap(con[row][j],con[i][j]);
                                  }
                                  break;
                            }
                      }
                }
                if(con[row][col]==0)
                {
                      row--;
                      continue;
                }
                for(k=1; k<=N; k++) 
                {
                      if(con[k][col]!=0&&k!=row)
                      {
                            temp=-(con[k][col]/con[row][col]);
                            for(t=col; t<=N+1; t++)
                            {
                                  con[k][t]=(temp*con[row][t])+con[k][t];
                            }
                      }
                }
          }
          for(k=row; k<N+1; k++)
                if(con[k][N+1]!=0) { return 0; }
          if(row==N+1) { return 1; }
          else
          {
                return 1<<(N-row+1);
          }
    }
    int main()
    {
          int T,i,j,x,y;
          scanf("%d",&T);
          while(T--)
          {
                scanf("%d",&N);
                for(i=1; i<=N; i++)
                {
                      scanf("%d",&beg[i]);
                }
                for(i=1; i<=N; i++)
                {
                      scanf("%d",&fin[i]);
                }
                scanf("%d%d",&x,&y);
                memset(con,0,sizeof(con));
                while(x!=0&&y!=0)
                {
                      con[y][x]=1;
                      scanf("%d%d",&x,&y);
                }
                for(i=1; i<=N; i++)
                {
                      con[i][i]=1;
                }
                for(i=1; i<=N; i++)
                {
                      if(beg[i]==fin[i])
                      {
                            con[i][N+1]=0;
                      }
                      else
                      {
                            con[i][N+1]=1;
                      }
                }
                int pp = function();
                if(pp)
                {
                      printf("%d
    ",pp);
                }
                else
                {
                      printf("Oh,it's impossible~!!
    ");
                }
          }
    }
    View Code
  • 相关阅读:
    数组练习1
    学习进度04
    求一个数组的最大子数组之和02
    求一个数组的最大子数组之和01
    学习进度03
    四则运算的功能添加版02
    第二周学习进度
    Right-BICEP 测试四则运算程序
    实现四则运算的功能添加版01
    本周实验PSP0 过程文档
  • 原文地址:https://www.cnblogs.com/crazyacking/p/4584545.html
Copyright © 2020-2023  润新知