zoukankan      html  css  js  c++  java
  • [Gauss]POJ1830 开关问题

    中文题 题意不多说

    这题乍一看 就是求个自由未知量个数 相当简单

    其实呢 其中要注意的细节还是很多的:

    1.光求了自由未知量个数 还不够 ∵求的是可行方案的总数  因此 答案是 2^(自由未知量个数)

    2.此题转化成方程组比较麻烦

      给了初始状态和最终状态 : ∵对于任意一个开关,最多只能进行一次开关操作。 ∴此开关的初始状态与最终状态不同(即异或)就需进行操作 

    3.还有一个坑!  

      操作第 I 个开关,第J个开关的状态也会变化。

      应将a[J-1][I-1]置1 而非a[I-1][J-1]     (因为是将 可以影响该位置改变的 位置置1

      1 int a[300][300];  // 增广矩阵
      2 int x[300];  //
      3 int free_x[300]; // 标记是否为自由未知量
      4 
      5 int n;
      6 void debug()
      7 {
      8     for(int i=0;i<n*n;i++)
      9     {
     10         for(int j=0;j<n*n;j++)
     11             printf("%d ", a[i][j]);
     12         printf("
    ");
     13     }
     14 }
     15 
     16 int Gauss(int n, int m) // n个方程 m个未知数 即 n行m+1列
     17 {
     18     //转换为阶梯形式
     19     int col=0, k, num=0;
     20     for(k=0;k<n && col<m;k++, col++)
     21     {//枚举行
     22         int max_r=k;
     23         for(int i=k+1;i<n;i++)//找到第col列元素绝对值最大的那行与第k行交换
     24             if(abs(a[i][col])>abs(a[max_r][col]))
     25                 max_r=i;
     26         if(max_r!=k)// 与第k行交换
     27             for(int j=col;j<m+1;j++)
     28                 swap(a[k][j], a[max_r][j]);
     29         if(!a[k][col])// 说明该col列第k行以下全是0了
     30         {
     31             k--;
     32             free_x[num++]=col;
     33             continue;
     34         }
     35         for(int i=k+1;i<n;i++)// 枚举要删除的行
     36             if(a[i][col])
     37                 for(int j=col;j<m+1;j++)
     38                     a[i][j]^=a[k][j];
     39     }
     40 
     41 //    debug();
     42 //    printf("%d %d
    ", col, k);
     43 
     44     for(int i=k;i<n;i++)
     45         if(a[i][col])
     46             return -1; // 无解
     47     return m-k;
     48 //    if(k<m)   //m-k为自由未知量个数
     49 //    {
     50 //        int stat=1<<(m-k);
     51 //        int ans=INT_MAX;
     52 //        for(int i=0;i<stat;i++)
     53 //        {
     54 //            int cnt=0;
     55 //            for(int j=0;j<m-k;j++)
     56 //                if(i&(1<<j))
     57 //                {
     58 //                    x[free_x[j]]=1;
     59 //                    cnt++;
     60 //                }
     61 //                else
     62 //                    x[free_x[j]]=0;
     63 //            for(int j=k-1;j>=0;j--)
     64 //            {
     65 //                int tmp;
     66 //                for(tmp=j;tmp<m;tmp++)
     67 //                    if(a[j][tmp])
     68 //                        break;
     69 //                x[tmp]=a[j][m];
     70 //                for(int l=tmp+1;l<m;l++)
     71 //                    if(a[j][l])
     72 //                        x[tmp]^=x[l];
     73 //                cnt+=x[tmp];
     74 //            }
     75 //            if(cnt<ans)
     76 //                ans=cnt;
     77 //        }
     78 //        return ans;
     79 //    }
     80 
     81 //    //  唯一解 回代
     82 //    for(int i=m-1;i>=0;i--)
     83 //    {
     84 //        x[i]=a[i][m];
     85 //        for(int j=i+1;j<m;j++)
     86 //            x[i]^=(a[i][j] && x[j]);
     87 //    }
     88 //    int ans=0;
     89 //    for(int i=0;i<n*n;i++)
     90 //        ans+=x[i];
     91 //    return ans;
     92 }
     93 
     94 
     95 void init()
     96 {
     97     n=4;
     98     memset(a, 0, sizeof(a));
     99     memset(x, 0, sizeof(x));
    100     for(int i=0;i<n;i++)
    101         for(int j=0;j<n;j++)
    102         {
    103             int t=i*n+j;
    104             a[t][t]=1;
    105             if(i>0)
    106                 a[(i-1)*n+j][t]=1;
    107             if(i<n-1)
    108                 a[(i+1)*n+j][t]=1;
    109             if(j>0)
    110                 a[i*n+j-1][t]=1;
    111             if(j<n-1)
    112                 a[i*n+j+1][t]=1;
    113         }
    114 }
    115 
    116 int s1[35], s2[35];
    117 int main()
    118 {
    119     int T;
    120     scanf("%d", &T);
    121     while(T--)
    122     {
    123         scanf("%d", &n);
    124         for(int i=0;i<n;i++)
    125             scanf("%d", &s1[i]);
    126         for(int i=0;i<n;i++)
    127             scanf("%d", &s2[i]);
    128         int X, Y;
    129         memset(a, 0, sizeof(a));
    130         memset(x, 0, sizeof(x));
    131         while(scanf("%d%d", &X, &Y))
    132         {
    133             if(!X && !Y)
    134                 break;
    135             a[Y-1][X-1]=1;
    136         }
    137         for(int i=0;i<n;i++)
    138         {
    139             a[i][i]=1;
    140             a[i][n]=s1[i]^s2[i];
    141         }
    142         int t=Gauss(n, n);
    143         if(t==-1)
    144         {
    145             printf("Oh,it's impossible~!!
    ");
    146             continue ;
    147         }
    148         printf("%d
    ", 1<<t);
    149     }
    150     return 0;
    151 }
    POJ 1830
  • 相关阅读:
    python+Appium自动化:记录遇到的坑
    python+Appium自动化:Appium元素检测
    python+Appium自动化:id元素定位
    python+Appium自动化:运行第一个appium脚本
    python+Appium自动化:Capability配置简介
    python+Appium自动化:Appium-desktop界面简介
    Appium简介以及环境安装
    monkeyrunner录制和回放功能
    monkeyrunner脚本录制和回放下载
    MonkeyRunner的简介与综合实践
  • 原文地址:https://www.cnblogs.com/Empress/p/4248154.html
Copyright © 2011-2022 走看看