您的位置:首页 > 其它

HDU 1226 超级密码 (bfs好题)

2015-03-15 11:46 435 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1226

wa了n发。。之前一直re。找了好久才发现是算c进制化十进制模n时,溢出了。所以得到的余数是负数,然后对数组就访问了非法位置。

代码如下。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=555;

struct key{
    int kk[maxn];//因为一个数无法存下密码,所以直接存c进制的数
    int len;//密码长度
};

int n,m,c;
int ff[22];
bool mod[5555];//因为密码是5000的倍数并且要最短,所以只需考虑对5000的余数.并且第一次出现该该余数就是最短的答案.

int mm(key s){//返回c进制数转换为十进制数后对n的余数.一直wa在这里
    int h=0;
    for(int i=0;i<s.len;i++)
        h=(h*c+s.kk[i])%n;
    return h;
}

/*
原写法
int quick(int x){
    int ans=1,k=c;
    while(x){
        if(x&1)
            ans=(ans*k)%n;
        k=(k*c)%n;
        x>>=1;
    }
    return ans%n;
}

int mm(key s){
    int h=0;
    for(int i=0;i<s.len;i++)
        h=(h+((s.kk[i]%n)*quick(i))%n)%n;
    return h;
}
*/

bool judge(key s){//判断是否全为0
    for(int i=s.len-1;i>=0;i--)
        if(s.kk[i]!=0) return true;
    return false;
}

bool bfs(){
    key t,ki;
    queue<key> q;
    memset(mod,false,sizeof(mod));
    for(int i=0;i<m;i++){
        t.len=0;
        t.kk[t.len++]=ff[i];
        q.push(t);
        if(ff[i]==0) continue;
        int x=mm(t);
        if(!mod[x]) mod[x]=true;
    }
    while(!q.empty()){
        t=q.front();
        q.pop();
        if(mm(t)==0 && judge(t)){
            for(int i=0;i<t.len;i++)
                if(t.kk[i]>=10) printf("%c",t.kk[i]-10+'A');
                else printf("%d",t.kk[i]);
            printf("\n");
            return true;
        }
        for(int i=0;i<m;i++){
            ki=t;
            ki.kk[ki.len++]=ff[i];
            int x=mm(ki);
            if(ki.len<500&&!mod[x]){//如果长度不超500并且该种余数不出现
                q.push(ki);
                if(!judge(ki)) continue;
                mod[x]=true;
            }
        }
    }
    return false;
}

int main(){
    int n_case;
    scanf("%d",&n_case);
    while(n_case--){
        scanf("%d%d%d",&n,&c,&m);
        for(int i=0;i<m;i++){
            char s[2];
            scanf("%s",s);
            if(s[0]>='0' && s[0]<='9') ff[i]=s[0]-'0';
            else ff[i]=s[0]-'A'+10;
        }
        sort(ff,ff+m);
        if(n==0){
            if(ff[0]==0) printf("0\n");
            else printf("give me the bomb please\n");
        }
        else if(!bfs())
            printf("give me the bomb please\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: