zoukankan      html  css  js  c++  java
  • hdu 2209 -- 翻纸牌游戏

    翻纸牌游戏

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2086    Accepted Submission(s): 747


    Problem Description
    有 一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌。但是 麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个 乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作。
     
    Input
    有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。
     
    Output
    对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。
     
    Sample Input
    01
    011
     
    Sample Output
    NO
    1
     
    原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=2209
     
     
    思路:利用位运算搜索(枚举)即可
     
    这是我ac代码 跑了593ms
     1 #include <iostream>
     2 #include <cstring>
     3 #include <queue>
     4 #include <cstdio>
     5 #define M (1<<21)
     6 using namespace std;
     7 int cnt[M];
     8 int BFS(int n,int m)
     9 {
    10 
    11     int t;
    12     queue<int>pq;
    13     cnt[n] = 1;
    14     pq.push(n);
    15     while(!pq.empty()){
    16         int v = (3<<(m-2));
    17         int vv = (7<<(m-3));
    18         int num = pq.front();
    19         pq.pop();
    20         for(int i = 1; i <= m; i++){
    21             if(i == 1){
    22                 t = num^v;
    23                 if(t == 0){
    24                     cnt[t] = cnt[num];
    25                     return cnt[t];
    26                 }
    27                 if(!cnt[t]){
    28                     cnt[t] = cnt[num]+1;
    29                     pq.push(t);
    30                 }
    31             }
    32             else{
    33                 t = num^vv;
    34                 if(t == 0){
    35                     cnt[t] = cnt[num];
    36                     return cnt[t];
    37                 }
    38                 if(!cnt[t]){
    39                     cnt[t] = cnt[num]+1;
    40                     pq.push(t);
    41                 }
    42                 vv = vv>>1;
    43             }
    44 
    45         }
    46     }
    47     return -1;
    48 }
    49 int main()
    50 {
    51     char str[25];
    52     while(cin>>str){
    53         memset(cnt,0,sizeof(cnt));
    54         int number = 0,steps;
    55         int len = strlen(str);
    56         for(int i = 0; str[i]; i++){
    57             number = number << 1;
    58             if(str[i] == '1'){
    59                 number = number | 1;
    60             }
    61         }
    62         if(number == 0){
    63             printf("0
    ");
    64             continue;
    65         }
    66         if(len == 1){
    67             if(number == 1){
    68                 printf("1
    ");
    69                 continue;
    70             }
    71         }
    72         if(len == 2){
    73             if(number == 3){
    74                 printf("1
    ");
    75             }
    76             else{
    77                 printf("NO
    ");
    78             }
    79             continue;
    80         }
    81         steps = BFS(number,len);
    82         if(steps == -1){
    83             printf("NO
    ");
    84         }
    85         else{
    86             printf("%d
    ",steps);
    87         }
    88     }
    89     return 0;
    90 }
    View Code
     
    下面是网上0ms代码,orz。。。
     
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <math.h>
     5 #include <stdlib.h>
     6 using namespace std;
     7 const int inf = 1<<30;
     8 
     9 char str[30];
    10 int a[30];
    11 
    12 int DFS(int i,int len,int m)
    13 {
    14     if(i == len)
    15         return a[i-1]?inf:m;
    16     if(a[i-1])
    17     {
    18         a[i-1] = !a[i-1];
    19         a[i] = !a[i];
    20         a[i+1] = !a[i+1];
    21         m++;
    22     }
    23     DFS(i+1,len,m);
    24 }
    25 
    26 int main()
    27 {
    28     int i,ans,len;
    29     while(~scanf("%s",str))
    30     {
    31         len = strlen(str);
    32         ans = inf;
    33         for(i = 0; i<len; i++)
    34             a[i] = str[i]-48;
    35         a[0]=!a[0];
    36         a[1]=!a[1];
    37         ans = min(ans,DFS(1,len,1));//第一张牌翻转
    38         for(i = 0; i<len; i++)
    39             a[i] = str[i]-48;
    40         ans = min(ans,DFS(1,len,0));//第一张牌没有手动翻转
    41         if(ans == inf)
    42             printf("NO
    ");
    43         else
    44             printf("%d
    ",ans);
    45 
    46     }
    47 
    48     return 0;
    49 }
    View Code
    Do one thing , and do it well !
  • 相关阅读:
    服务器消息机制实现记录
    转载SQL经典代码按某一字段分组取最大(小)值所在行的数据
    记录js获取当前URL
    (原创)xilinx IP建立向导创建的目录和文件都是做什么的?由错误ERROR:HDLCompiler:Instantiating <xx> from unknown module <xx>引发的思考
    [转]NTFS3G的安装和配置
    (原创)Notepad++怎么实现双视图/双窗口?
    (原创)Quartus硬件工程路径改变,nios工程该怎么办?
    (原)verilog中的reg类型变量,一定会综合出触发器吗?
    (Windows)使用纯净版本的系统碟安装系统后没有网卡驱动怎么办?
    [转]NIOS_II的Boot过程分析
  • 原文地址:https://www.cnblogs.com/ubuntu-kevin/p/3727050.html
Copyright © 2011-2022 走看看