• [Swust OJ 781]--牛喝水


    Time limit(ms): 1000    Memory limit(kb): 65535
     

    The cows have a line of 20 water bowls from which they drink. The bowls can be either right-side-up (properly oriented to serve refreshing cool water) or upside-down (a position which holds no water). They want all 20 water bowls to be right-side-up and thus use their wide snouts to flip bowls. 

    Their snouts, though, are so wide that they flip not only one bowl but also the bowls on either side of that bowl (a total of three or -- in the case of either end bowl -- two bowls). 

    Given the initial state of the bowls (1=undrinkable, 0=drinkable -- it even looks like a bowl), what is the minimum number of bowl flips necessary to turn all the bowls right-side-up?

    Description

    Line 1: A single line with 20 space-separated integers

    Input

    Line 1: The minimum number of bowl flips necessary to flip all the bowls right-side-up (i.e., to 0). For the inputs given, it will always be possible to find some combination of flips that will manipulate the bowls to 20 0's.

    Output
    1
    0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0
    Sample Input
    1
    3
    Sample Output

    Explanation of the sample: 

    Flip bowls 4, 9, and 11 to make them all drinkable: 
    0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 [initial state] 
    0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 [after flipping bowl 4] 
    0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 [after flipping bowl 9] 
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [after flipping bowl 11]

    题目大意:一只牛能把碗翻转过来,(由于嘴太大 ^_^ )同时会把他左右的碗全部翻转,1代表需要翻转的碗,问最少可以几次把碗全部翻转(0表示)

    这道题呐,用dfs 也能做 ,以前就是dfs  a掉的,今天做了(杭电的Stange Billboard(可以看看))位运算后想了想这不就是一个行为1,列为20的位位运算吗,(上面的说过行大于列就转置,不然第一行枚举2^20,,转置了就只有两种可能了)~~

    先上dfs的代码 100ms(反正不低于100)

     1 #include<iostream>
     2 using namespace std;
     3 int bowl[21], step, flag;
     4 int range()
     5 {
     6     int i;
     7     for (i = 0; i<20; i++)
     8     if (bowl[i] == 1)
     9         return 0;
    10     return 1;
    11 }
    12 void turn(int i)
    13 {
    14     bowl[i] = !bowl[i];
    15     if (i>0)
    16         bowl[i - 1] = !bowl[i - 1];
    17     if (i<19)bowl[i + 1] = !bowl[i + 1];
    18 }
    19 void DFS(int i, int dp)
    20 {
    21     if (step == dp)
    22     {
    23         flag = range();
    24         return;
    25     }
    26     if (i >= 20 || flag) return;
    27     turn(i);
    28     DFS(i + 1, dp + 1);
    29     turn(i);
    30     DFS(i + 1, dp);
    31 }
    32 int main()
    33 {
    34     int i;
    35     for (i = 0; i < 20; i++)
    36         cin >> bowl[i];
    37     for (step = 0; step<20; step++)
    38     {
    39         flag = 0;
    40         DFS(0, 0);
    41         if (flag) break;
    42     }
    43     cout << step << endl;
    44     return 0;
    45 }
    View Code

    至于用位运算0ms  直接水过~~~

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 #define inf 0x7fffffff
     5 #define min(a,b) a<b?a:b
     6 int mpt[20], tmp[20], sign[20];
     7 int main(){
     8     int i, j, cnt, minn = inf, x;
     9     for (j = 0; j < 20; j++){
    10         cin >> x;
    11         if (x)
    12             mpt[j] |= 1 << 0;
    13     }
    14 //行为1,列为20直接转置
    15     for (i = 0; i < 1 << 1; i++){
    16         for (j = 0; j < 20; j++)
    17             tmp[j] = mpt[j];
    18         for (j = 0; j < 20; j++){
    19             sign[j] = j == 0 ? i : tmp[j - 1];
    20             tmp[j] ^= sign[j];
    21             tmp[j + 1] ^= sign[j];
    22         }
    23         if (!tmp[19]){
    24             cnt = 0;
    25             for (j = 0; j < 20; j++)
    26             if (sign[j] & 1)
    27                 cnt++;
    28         }
    29         minn = min(minn, cnt);
    30     }
    31     cout << minn << endl;
    32     return 0;
    33 }
    View Code

     关于位运算可以戳戳这里:http://www.cnblogs.com/zyxStar/p/4564335.html

  • 相关阅读:
    codevs 1102 采药 2005年NOIP全国联赛普及组
    codevs 1058 合唱队形 2004年NOIP全国联赛提高组
    动归题目
    友好城市//未测,不知对错
    codevs 1044 拦截导弹 1999年NOIP全国联赛提高组
    codevs 5294 挖地雷
    codevs 1576 最长严格上升子序列
    [BZOJ3289]Mato的文件管理
    [CodeVS1299]切水果
    [TYVJ1473]校门外的树3
  • 原文地址:https://www.cnblogs.com/zyxStar/p/4541059.html
Copyright © 2020-2023  润新知