nyoj 929 密码宝盒

密码宝盒

时间限制:2000 ms  |  内存限制:65535 KB

难度:3

描述

M得到了一个宝盒,可惜打开这个宝盒需要一组神奇的密码,然而在宝盒的下面

有关于密码的提示信息:密码是一个C进制的数,并且只能由给定的M个数字中的某些构成,密码不超过500位,同时密码是一个给定十进制整数N的正整数倍,

如果这样的密码存在,那么你就可以打开宝盒并得到宝贝,如果不存在

这样的密码......那你就只能收藏这个宝盒了.

输入

输入一个T,表示有T组测试数据,(T≤500)
接下来输入N,C,M(N,C,M如上所述)( 0≤N≤5000, 1≤M≤16 , 2≤C≤16 )
然后M个数,表示密码中含有哪些数字。(输入保证合法)
A来表示10, B来表示11, C来表示12 , D来表示13, E来表示14, F来表示15

输出

输出:密码如果存在,输入最小的那个为密码,不存在”So Sorry.”(密码不含前导零)

样例输入

3

22 10 3

7 0 1

 

2 10 1

1

 

25 16 3

A B C

样例输出

110

So Sorry.

CCB

#include <queue>  
#include <string>  
#include <stdio.h>  
#include <string.h>  
#include <algorithm>  
using namespace std;  
const int N = 5005;  
bool vis[N];  
string ans;  
int a[17],pre[N],ansAt[N],n,m,c;  
int ctoi(char c)  
{  
    return c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;  
}  
char itoc(int i)  
{  
    return i <= 9 ? i + '0' : i + 'A' - 10;  
}  
bool bfs()  
{  
    queue<int> q;  
    q.push(0);  
    while(!q.empty())  
    {  
        int cur = q.front();q.pop();  
        for(int i=0;i<m;i++)  
        {  
            int nxt = (cur * c + a[i]) % n;  
            if(cur == 0 && a[i] == 0 || vis[nxt])  
                       continue;  
            vis[nxt] = true;  
            ansAt[nxt] = a[i];  
            pre[nxt] = cur;  
            if(nxt == 0)  
                      return true;  
            q.push(nxt);  
        }  
    }  
    return false;  
}  
  
bool check()  
{  
    ans = "";  
    int p = 0;  
    do  
    {  
        ans += itoc(ansAt[p]);  
        p = pre[p];  
    }while(p);  
    return (int)ans.size() <= 500;  
}  
  
int main()  
{  
    int T;  
    scanf("%d",&T);  
    while(T--)  
    {  
        memset(vis,false,sizeof(vis));  
        scanf("%d%d%d",&n,&c,&m);  
        for(int i=0;i<m;i++)  
        {  
            char num[3];  
            scanf("%s",num); //以免存入空格 
            a[i] = ctoi(num[0]);  
        }  
        sort(a,a+m);  
        if(n == 0)   
        {  
            puts(a[0] == 0 ? "0" : "So Sorry.");  
            continue;  
        }  
        if(bfs() && check())  
        {  
            for(int i=(int)ans.size()-1;i>=0;i--)  
                putchar(ans[i]);  
            puts("");  
        }  
        else  
            puts("So Sorry.");  
    }  
    return 0;  
}  

  

很高兴能为您解答密码宝盒问题的递归解法。 首先,我们需要明确一些问题: 1. 给定数字M和倍数N。 2. 需要在M个数字中选择一些数字组成一个数字。 3. 该数字需要是N的倍数。 接下来,我们可以使用递归解法来解决该问题。具体步骤如下: 1. 定义一个递归函数,它接受三个参数:当前已经组成的数字(初始值为0)、已选数字的个数和给定数字的集合。 2. 在递归函数中,遍历给定数字的集合,依次选取每个数字进行尝试。如果选取该数字后,组成的数字仍然小于等于原来的数字,那么我们可以将该数字添加到当前已经组成的数字中,并递归调用该函数。 3. 在递归调用中,我们需要检查新组成的数字是否是N的倍数。如果是,则输出该数字并结束程序;否则继续递归调用。 4. 如果已选数字的个数等于M,但是没有找到符合条件的数字,那么输出“No solution”。 下面是一个简单的实现代码: ```python def solve(cur_num, selected, nums, n): if selected == len(nums): if cur_num % n == 0: print(cur_num) exit() return for i in range(len(nums)): new_num = cur_num * 10 + nums[i] if new_num <= cur_num: continue solve(new_num, selected + 1, nums, n) ``` 您可以将该函数作为主函数的子函数调用,并传入相应的参数,如下所示: ```python def main(): m = 3 n = 7 nums = [1, 2, 3, 4, 5, 6, 7, 8, 9] solve(0, 0, nums, n) print("No solution") ``` 在上面的示例中,我们将M设置为3,倍数N设置为7,数字集合为1到9。您可以根据实际情况进行修改。运行该程序后,如果找到符合条件的数字,程序会输出该数字并结束;否则输出“No solution”。 希望这个解法能够帮助到您,如果您有任何问题,请随时联系我。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值