hdu1226

来源:互联网 发布:淘宝第三层级什么意思 编辑:程序博客网 时间:2024/05/18 03:19

题目链接:超级密码

题目大意:找出最小的一个数,满足由给定的

(1)m个数字组成(有些数字可以不用)

(2)可以整除一个数n

由于最多可以有500位数,每个数字最多有16种情况,单纯暴力肯定会TLE.

--》bfs

用bool num[16]记录给出的m个数字,一步步遍历

由于数字位数大,用大了大数求余

int mod(const node &cur){    int tmp=0;    for(int i=0;i<cur.len;i++){        tmp=(tmp*c+cur.s[i])%n;    }    return tmp;}
剪枝技巧:

A%X == B%X (设A<B)

那么 (A*10+Ki)%X==(B*10+Ki)%X

所以A,B之中我们只要取前面的A就行,因为题目要取最小的数,通过同余我们可以知道,A和B这两个数在末尾添加任何相同的数MOD X之后的余数都是一样的,因此对于比A大的数我们就没有必要去扩展了。

#include <stdio.h>#include <queue>#include <memory.h>#include <algorithm>using namespace std;struct node{    int s[505];    int len;};int c,n,m,maxm;bool num[20];bool vis[5005];void init(){    maxm=-1;    memset(num,0,sizeof(num));    memset(vis,0,sizeof(vis));}void print(const node &cur){    for(int i=0;i<cur.len;i++){        if(cur.s[i]<=9)printf("%d",cur.s[i]);        else printf("%c",cur.s[i]-10+'A');    }    printf("\n");}int mod(const node &cur){    int tmp=0;    for(int i=0;i<cur.len;i++){        tmp=(tmp*c+cur.s[i])%n;    }    return tmp;}void bfs(){    int r;    queue<node>q;    node cur;    for(int i=1;i<=maxm;i++){        if(num[i]){            cur.s[0]=i;            cur.len=1;            if((r=mod(cur))==0){                print(cur);                return;            }            else if(!vis[r]){                vis[r]=true;                q.push(cur);            }        }    }    while(!q.empty()){        cur=q.front();        q.pop();        for(int i=0;i<=maxm;i++){            if(num[i]){                cur.s[cur.len]=i;                cur.len++;                if((r=mod(cur))==0){                    print(cur);                    return;                }                else if(!vis[r]&&cur.len<499){                    vis[r]=true;                    q.push(cur);                }                cur.len--;            }        }    }    printf("give me the bomb please\n");}int main(){    //freopen("in.txt","r",stdin);    int T,tmp;    char ch[2];    scanf("%d",&T);    while(T--){        init();        scanf("%d %d",&n,&c);        scanf("%d",&m);        for(int i=0;i<m;i++){            scanf("%s",&ch);            if(ch[0]<='9') tmp=ch[0]-'0';            else tmp=ch[0]-'A'+10;            num[tmp]=true;            maxm=max(maxm,tmp);        }        if(n==0){            if(num[0])printf("0\n");            else  printf("give me the bomb please\n");        }        else bfs();    }    return 0;}



0 0
原创粉丝点击