• HDU1226 搜索 bfs xingxing在努力


      这道题就是给你M个C进制的数, 然后让你求最小的数, 这个数是N的整数倍。。搜索即可:剪枝条件:假设有两个数模N都为0那么我们就可以舍弃较大的那个数。为什么可以这样,我们可以假设这两个数是a, b a  = b (mod N)  => a*C + d = b*C + d (mod N), 然后注意取模的时候要用大数取摸的方式。。坑点:N可能为0, 对于N==0的时候,我们应该特殊判断, 代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    int N, C, M;    //c进制的密码
    char num[20];
    
    struct State
    {
        char st[505];
        int len;
    }temp, res;
    
    int vis[5000 + 10];
    int mod(State &st)
    {
        int tmp = 0;
        for(int i=0; i<st.len; i++)
        {
            int num;
            if(st.st[i]>='0' && st.st[i]<='9')  num = st.st[i] - '0';
            else if(st.st[i]>='A' && st.st[i]<='F') num = st.st[i]-'A'+10;
            tmp = (tmp*C + num)%N;
        }
        return tmp;
    }
    
    void print(State &u)
    {
        for(int i=0; i<u.len; i++)
        {
            printf("%c", u.st[i]);
        }
        printf("
    ");
    }
    
    int bfs()
    {
        memset(vis, 0, sizeof(vis));
        queue<State> que;
        for(int i=0; i<M; i++)
        {
            temp.len = 1;
            temp.st[0] = num[i];
            if(num[i] == '0') continue;
            if(!vis[mod(temp)])
            {
                que.push(temp);
                vis[mod(temp)] = 1;
            }
        }
        //printf("%d
    ", que.size());
        while(!que.empty())
        {
            State u = que.front(); que.pop();
            if(mod(u) == 0)
            {
                res = u;
                return 1;
            }
            if(u.len>=500) continue;
            for(int i=0; i<M; i++)
            {
                State v = u;
                v.st[v.len++] = num[i];
                if(!vis[mod(v)])
                {
                    que.push(v);
                    vis[mod(v)] = 1;
                }
            }
        }
        return -1;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d%d%d", &N, &C, &M);
    
            int tp = 0;
            for(int i=0; i<M; i++)
            {
                char s[10];
                scanf("%s", s);
                num[tp++] = s[0];
            }
            sort(num, num+M);
    /*        for(int i=0; i<M; i++)    printf("%c ", num[i]);
            printf("
    ");*/
            if(N == 0)
            {
                if(num[0] == '0') printf("0
    ");
                else printf("give me the bomb please
    "); 
            }
            else 
            {
                if(bfs() > 0)
                    print(res);
                else printf("give me the bomb please
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    用硬件卡克隆Linux集群
    基于Linux系统WINE虚拟机技术的研究
    Rpm另类用法加固Linux安全
    基于TC技术的网络流量控制实战
    开源世界里的七剑
    借Stunnel工具保护E-mail服务器
    如何应对DDOS网络攻击(之二)
    如何应对DDOS网络攻击
    Leetcode-983 Minimum Cost For Tickets(最低票价)
    Leetcode-413 Arithmetic Slices(等差数列划分)
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5022051.html
Copyright © 2020-2023  润新知