poj 1830 開關問題 (高斯消元)

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   資料   for   

題目連結

題意:給定N(N < 29)個開關,每個開關開啟和關閉的時候會引起另外一個開關的變化,本來為開啟的會變成關閉,

本來關閉的會變成開啟。給定N個開關的初始狀態和終止狀態,以及關聯的開關關係,求共有多少種方案從初始狀態變成終止狀態(不計順序,並且每個開關只能操作至多一次)。

分析:

由於開關只有開啟和關閉兩種狀態,所以對於每個開關的開啟和關閉,組合一下總共有2^N種情況,枚舉所有情況判可行性,對於這個資料量來說是不現實的,需要想辦法最佳化。

start + x(i) * A(i) = end

x(i) * A(i) = start ^ end 即當開始狀態和結束狀態不同的時候才取1 來改變狀態。。

係數矩陣A[i][j]代表了開關之間的連帶關係:

1) 如果第j個開關的操作能夠影響第i個開關的狀態,那麼A[i][j] = 1;

2) 如果第j個開關的操作不影響第i個開關的狀態,那麼A[i][j] = 0;

3) 特殊的A[i][i] = 1(開關本身的操作必然會影響自己的目前狀態);

但是還是不理解為什麼不是前面 影響 後面????

 

  1 #include <iostream>  2 #include <cstdio>  3 #include <cstring>  4 #include <cstdlib>  5 #include <cmath>  6 #include <algorithm>  7 #define LL __int64  8 const int maxn = 30+10;  9 using namespace std; 10 int equ, var, fn; 11 int a[maxn][maxn], x[maxn]; 12  13 int gcd(int a, int b) 14 { 15     return b==0?a:gcd(b, a%b); 16 } 17 int lcm(int a, int b) 18 { 19     return a*b/gcd(a, b); 20 } 21 int Gauss() 22 { 23     int x_mo; 24     x_mo = 2; 25     int i, j, k, max_r, col; 26     int ta, tb, LCM; 27     col = 0; 28  29     for(k = 0; k<equ && col<var; k++, col++) 30     { 31         max_r = k; 32         for(i = k+1; i < equ; i++) 33             if(abs(a[i][col])>abs(a[max_r][col])) 34             max_r = i; 35  36         if(max_r != k) 37             for(j = k; j < var+1; j++) 38             swap(a[k][j], a[max_r][j]); 39  40         if(a[k][col]==0) 41         { 42             k--; 43             continue; 44         } 45         for(i = k+1; i < equ; i++) 46         { 47             if(a[i][col] != 0) 48             { 49                 LCM = lcm(abs(a[i][col]), abs(a[k][col])); 50                 ta = LCM/abs(a[i][col]); 51                 tb= LCM/abs(a[k][col]); 52                 if(a[i][col]*a[k][col] < 0) tb = -tb; 53  54                 for(j = col; j < var+1; j++) 55                 a[i][j] = ((a[i][j]*ta - a[k][j]*tb)%x_mo+x_mo)%x_mo; 56             } 57         } 58     } 59     for(i = k; i < equ; i++) 60     if(a[i][col] != 0) 61     return -1; 62  63     if(k < var) 64         return var-k; 65     return 0; 66 } 67 int main() 68 { 69     int i, t, n; 70     int b[maxn], e[maxn], c, d; 71     scanf("%d", &t); 72     while(t--) 73     { 74         cin>>n; 75         equ = n; 76         var = n; 77         memset(a, 0, sizeof(a)); 78         for(i = 0; i < n; i++) 79         cin>>b[i]; 80         for(i = 0; i < n; i++) 81         cin>>e[i]; 82         while(cin>>c>>d) 83         { 84             if(c==0 && d==0) break; 85             a[d-1][c-1] = 1; //注意題目裡是從1開始的,注意是c在後,後面影響前面。但是還是不理解為什麼 86         } 87         for(i = 0; i < n; i++) 88             a[i][i] = 1; 89         for(i = 0; i < n; i++) 90         a[i][n] = (b[i]^e[i]); //當開始狀態和結束狀態不同的時候才取1 來改變狀態 91         fn = Gauss(); 92         if(fn==-1) 93         printf("Oh,it‘s impossible~!!\n"); 94         else 95         { 96             fn = (1<<fn); //因為有fn個變元,而有0,1兩種狀態,所以情況數是2^fn。 97             cout<<fn<<endl; 98         } 99     }100     return 0;101 }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.