• HDU-1226 超级密码 (BFS+剪枝)


    Problem Description
    Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息:
    密 码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足 条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.
    注意:由于宝藏的历史久远,当时的系统最多只能保存500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
     
    Input
    输 入数据的第一行是一个整数T(1<=T<=300),表示测试数据的数量.每组测试数据的第一行是两个整数N(0<=N& lt;=5000)和C(2<=C<=16),其中N表示的是题目描述中的给定十进制整数,C是密码的进制数.测试数据的第二行是一个整数 M(1<=M<=16),它表示构成密码的数字的数量,然后是M个数字用来表示构成密码的数字.两个测试数据之间会有一个空行隔开.

    注意:在给出的M个数字中,如果存在超过10的数,我们约定用A来表示10,B来表示11,C来表示12,D来表示13,E来表示14,F来表示15.我保证输入数据都是合法的.
     
    Output
    对于每组测试数据,如果存在要求的密码,则输出该密码,如果密码不存在,则输出"give me the bomb please".

    注意:构成密码的数字不一定全部都要用上;密码有可能非常长,不要试图用一个整型变量来保存密码;我保证密码最高位不为0(除非密码本身就是0).
     
    Sample Input
    3
    22 10
    3
    7 0 1
    2 10
    1
    1
    25 16
    3
    A B C
     
    Sample output
    110
    give me the bomb please
    CCB
     
    题目分析:由于是求最小的密码,显然就应该用BFS了,其实用DFS加上剪枝(这的剪枝比BFS代码中的剪枝还要多那么一丢丢)也能跑出正确的结果,但仍然会TLE。同余剪枝:当刚出队列的状态转移到下一个时,对n的模已经出现过了,则剪去。
     
    代码如下:
     AC的BFS+剪枝:
     1 # include<iostream>
     2 # include<cstdio>
     3 # include<string>
     4 # include<queue>
     5 # include<cstring>
     6 # include<algorithm>
     7 using namespace std;
     8 struct node
     9 {
    10     string ans;
    11     int val;
    12     node(string s,int m):ans(s),val(m){}
    13     bool operator < (const node &a) const {
    14         if(ans.size()==a.ans.size())
    15             return ans>a.ans;
    16         return ans.size()>a.ans.size();
    17     }
    18 };
    19 int vis[5005],n,m,c,num[20];
    20 int get()
    21 {
    22     char ch;
    23     cin>>ch;
    24     if(ch>='0'&&ch<='9')
    25         return ch-'0';
    26     return ch-'A'+10;
    27 }
    28 void bfs()
    29 {
    30     memset(vis,0,sizeof(vis));
    31     priority_queue<node>q;
    32     for(int i=0;i<m;++i){
    33         if(num[i]==0)
    34             continue;
    35         string s;
    36         if(num[i]<=9)
    37             s+=num[i]+'0';
    38         else
    39             s+=num[i]-10+'A';
    40         vis[num[i]%n]=1;
    41         q.push(node(s,num[i]%n));
    42     }
    43     while(!q.empty())
    44     {
    45         node u=q.top();
    46         q.pop();
    47         if(u.val==0){
    48             cout<<u.ans<<endl;
    49             return ;
    50         }
    51         if(u.ans.size()>=500)
    52             continue;
    53         for(int i=0;i<m;++i){
    54             int now=(u.val*c+num[i])%n;
    55             if(vis[now])
    56                 continue;
    57             string s=u.ans;
    58             if(num[i]<=9)
    59                 s+=num[i]+'0';
    60             else
    61                 s+=num[i]-10+'A';
    62             vis[now]=1;
    63             q.push(node(s,now));
    64         }
    65     }
    66     printf("give me the bomb please
    ");
    67 }
    68 int main()
    69 {
    70     int T;
    71     scanf("%d",&T);
    72     while(T--)
    73     {
    74         scanf("%d%d",&n,&c);
    75         scanf("%d",&m);
    76         for(int i=0;i<m;++i)
    77             num[i]=get();
    78         sort(num,num+m);
    79         if(n==0){
    80             if(num[0]==0)
    81                 printf("0
    ");
    82             else
    83                 printf("give me the bomb please
    ");
    84             continue;
    85         }
    86         bfs();
    87     }
    88     return 0;
    89 }
    View Code

    TLE的DFS+剪枝写法:

     1 # include<iostream>
     2 # include<cstdio>
     3 # include<string>
     4 # include<cstring>
     5 # include<algorithm>
     6 using namespace std;
     7 int vis[5005],n,m,c,num[20],flag;
     8 string aans;
     9 int get()
    10 {
    11     char ch;
    12     cin>>ch;
    13     if(ch>='0'&&ch<='9')
    14         return ch-'0';
    15     return ch-'A'+10;
    16 }
    17 bool is_smaller(string s1,string s2)
    18 {
    19     if(s1.size()<s2.size())
    20         return true;
    21     if(s1.size()==s2.size()&&s1<s2)
    22         return true;
    23     return false;
    24 }
    25 void dfs(string ans,int s)
    26 {
    27     if(ans.size()>500)
    28         return ;
    29     if(s==0){
    30         if(!flag){
    31             aans=ans;
    32             flag=1;
    33         }
    34         else{
    35             if(is_smaller(ans,aans))
    36                 aans=ans;
    37         }
    38         return ;
    39     }
    40     //cout<<ans<<endl;
    41     if(flag){
    42         if(aans.size()<ans.size())
    43             return ;
    44         if(aans.size()==ans.size()&&ans>aans)
    45             return ;
    46     }
    47     string temp=ans;
    48     for(int i=0;i<m;++i){
    49         int ns=(s*c+num[i])%n;
    50         if(vis[ns])
    51             continue;
    52         if(num[i]<=9)
    53             ans+=num[i]+'0';
    54         else
    55             ans+=num[i]+'A'-10;
    56         vis[ns]=1;
    57         dfs(ans,ns);
    58         vis[ns]=0;
    59         ans=temp;
    60     }
    61 }
    62 int main()
    63 {
    64     int T;
    65     scanf("%d",&T);
    66     while(T--)
    67     {
    68         scanf("%d%d",&n,&c);
    69         scanf("%d",&m);
    70         for(int i=0;i<m;++i)
    71             num[i]=get();
    72         sort(num,num+m);
    73         flag=0;
    74         memset(vis,0,sizeof(vis));
    75         for(int i=0;i<m;++i){
    76             //cout<<num[i]<<endl;
    77             string ans;
    78             if(num[i]==0)
    79                 continue;
    80             if(num[i]<=9)
    81                 ans+=num[i]+'0';
    82             else
    83                 ans+=num[i]-10+'A';
    84             if(num[i]%n==0){
    85                 aans=ans;
    86                 flag=1;
    87                 break;
    88             }
    89             vis[num[i]%n]=1;
    90             dfs(ans,num[i]%n);
    91             vis[num[i]%n]=0;
    92         }
    93         if(!flag)
    94             printf("give me the bomb please
    ");
    95         else
    96             cout<<aans<<endl;
    97     }
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    【ACM-ICPC 2018 南京赛区网络预赛 L】Magical Girl Haze
    【Manthan, Codefest 18 (rated, Div. 1 + Div. 2) C】Equalize
    【Manthan, Codefest 18 (rated, Div. 1 + Div. 2) B】Reach Median
    工作总结二
    学习总结
    快速WCF
    EF+linq的增删改查
    JAVASCRIPT闭包以及原型链
    CSS声明各个浏览器私有属性的命名前缀
    mvc的model验证,ajaxhelper,验证机制语法
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4734497.html
Copyright © 2020-2023  润新知