zoukankan      html  css  js  c++  java
  • 【POJ】3185 The Water Bowls

    题意:有20个数字,0或1。如果改变一个数的状态,它左右两边的两个数的状态也会变反。问从目标状态到全0,至少需要多少次操作。

    显然,问题可以从目标状态到全0 转化为 全0到目标状态。

    于是可以列出方程组,每行一个数的状态。

    为了知道操作次数,那么就要知道未知数为1有多少个,所以就要解方程组,解方程组就不得不枚举自由元了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define MAXN 20
     5 #define MAXM 25
     6 #define oo 0x7FFFFFFF
     7 using namespace std;
     8 int g[MAXM][MAXM], tmp[MAXM], x[MAXM];
     9 int ans;
    10 bool Read() {
    11     int i;
    12     for (i = 0; i < MAXN; i++) {
    13         if (scanf("%d", &g[i][MAXN]) == EOF)
    14             return false;
    15     }
    16     return true;
    17 }
    18 int Cal() {
    19     int i, j, k, cnt;
    20     k = cnt = 0;
    21     for (i = MAXN - 1; i >= 0; i--) {
    22         if (g[i][i]) {
    23             x[i] = g[i][MAXN];
    24             for (j = i + 1; j < MAXN; j++)
    25                 x[i] ^= x[j] && g[i][j];
    26         } else
    27             x[i] = tmp[k++];
    28         if (x[i])
    29             cnt++;
    30     }
    31     return cnt;
    32 }
    33 void DFS(int now, int cnt) {
    34     if (cnt == 0)
    35         ans = min(ans, Cal());
    36     else {
    37         tmp[now] = 0;
    38         DFS(now + 1, cnt - 1);
    39         tmp[now] = 1;
    40         DFS(now + 1, cnt - 1);
    41     }
    42 }
    43 void Gauss() {
    44     int r, c, i, j;
    45     for (c = r = 0; c < MAXN; c++, r++) {
    46         for (i = r; i < MAXN; i++) {
    47             if (g[i][c])
    48                 break;
    49         }
    50         if (i >= MAXN)
    51             r--;
    52         else {
    53             if (i != r) {
    54                 for (j = 0; j <= MAXN; j++)
    55                     swap(g[i][j], g[r][j]);
    56             }
    57             for (i = r + 1; i < MAXN; i++) {
    58                 if (g[i][c]) {
    59                     for (j = c; j <= MAXN; j++)
    60                         g[i][j] ^= g[r][j];
    61                 }
    62             }
    63         }
    64     }
    65     DFS(0, MAXN - r);
    66 }
    67 int main() {
    68     int i;
    69     while (Read()) {
    70         for (i = 0; i < MAXN; i++) {
    71             g[max(i - 1, 0)][i] = 1;
    72             g[i][i] = 1;
    73             g[min(MAXN - 1, i + 1)][i] = 1;
    74         }
    75         ans = oo;
    76         Gauss();
    77         printf("%d\n", ans);
    78     }
    79     return 0;
    80 }
    新博客:www.zhixiangli.com
  • 相关阅读:
    人生转折点:弃文从理
    人生第一站:大三暑假实习僧
    监听器启动顺序和java常见注解
    java常识和好玩的注释
    182. Duplicate Emails (Easy)
    181. Employees Earning More Than Their Managers (Easy)
    180. Consecutive Numbers (Medium)
    178. Rank Scores (Medium)
    177. Nth Highest Salary (Medium)
    176. Second Highest Salary(Easy)
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2668280.html
Copyright © 2011-2022 走看看