2012Chhengdu K - Yet Another Multiple Problem

K - Yet Another Multiple Problem

Time Limit:20000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status Practice HDU 4474

Appoint description: 
System Crawler  (2014-10-16)

Description

There are tons of problems about integer multiples. Despite the fact that the topic is not original, the content is highly challenging. That’s why we call it “Yet Another Multiple Problem”. 
In this problem, you’re asked to solve the following question: Given a positive integer n and m decimal digits, what is the minimal positive multiple of n whose decimal notation does not contain any of the given digits?

Input

There are several test cases. 
For each test case, there are two lines. The first line contains two integers n and m (1 ≤ n ≤ 10 4). The second line contains m decimal digits separated by spaces. 
Input is terminated by EOF.

Output

For each test case, output one line “Case X: Y” where X is the test case number (starting from 1) while Y is the minimal multiple satisfying the above-mentioned conditions or “-1” (without quotation marks) in case there does not exist such a multiple.

Sample Input

2345 3
7 8 9
100 1
0

Sample Output

Case 1: 2345
Case 2: -1

题意:以样例为例,2345的最小倍数,不包含给出的三个数7 8 9

思路:bfs,以0-9中能够使用的数字bfs,一位一位的加在后面,当第一个出现数字x%n==0时,则x为解。

这里需要的知识点是,(x*10+i)%n == (x%n)*10+i,所以只需要存(x%n)所有可能,根据抽屉原理,节点数不超过n,这样就可以很快搜到了。

存结果的话,因为结果有可能很长很长,可以在结构体里面加一个字符串,从前面的点的字符串更新过来,也就是在最后加一个‘i‘,或者开数组存这个数的结尾num[i],然后和前面更新过来的节点pre[i].

注意:只有0为可行数字的情况的特殊处理

错在一开始vis数组在第一个数时没置1,只有0为可行数字的情况的特殊处理处理错,还有新的数没%n就放越界。

数组bfs:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #define M(a,b) memset(a,b,sizeof(a))
 6 #define INF 0x3f3f3f3f
 7
 8 using namespace std;
 9
10 int n,m;
11
12 int pre[1000005],num[1000005];
13 int can[15];
14 int que[1000005];
15 int vis[1000005];
16 int res[1000005];
17
18 int bfs()
19 {
20     int head = -1;
21     int tail = 0;
22     M(vis,0);
23     que[0] = 0;
24     for(int i = 1;i<10;i++)
25     {
26         if(!can[i])
27         {
28             if(i%n==0) {num[i] = i,pre[i] = 0; return i;}
29             else num[i] = i,pre[i] = 0, vis[i] = 1, que[tail] = i,tail++;
30         }
31     }
32     while(head<tail)
33     {
34         head++;
35         int tmp = que[head];
36         //cout<<tmp<<endl;
37         for(int i = 0;i<10;i++)
38         {
39             if(i==0&&tmp==0) continue;
40             //cout<<i<<endl;
41             if(!can[i])
42             {
43                 int u = tmp*10+i;
44                 int t = u%n;
45                 if(!vis[t])
46                 {
47                 if(t==0) {pre[u] = tmp, num[u] = i;return u;}
48                 else{
49                     //cout<<t<<‘ ‘<<i<<endl;
50                     pre[t] = tmp, num[t] = i;
51                     vis[t] = 1;
52                     que[tail] = t;
53                     tail++;
54                 }
55                 }
56             }
57         }
58     }
59     return -1;
60 }
61
62 int main()
63 {
64     int cas = 1;
65     while(scanf("%d%d",&n,&m)==2)
66     {
67         M(pre,0);
68         M(num,0);
69         M(can,0);
70         for(int i = 0;i<m;i++)
71         {
72             int a;
73             scanf("%d",&a);
74             can[a] = 1;
75         }
76         pre[0] = -1;
77         int ans = bfs();
78         if(m==10) {printf("Case %d: -1\n",cas++); continue;}
79         printf("Case %d: ",cas++);
80         if(ans == -1) puts("-1");
81         else{
82             int cnt = 0;
83             for(int i = ans;pre[i]!=-1;i = pre[i])
84                 res[cnt++] = num[i];
85             for(int i = cnt-1;i>0;i--)
86                 printf("%d",res[i]);
87             printf("%d\n",res[0]);
88         }
89     }
90     return 0;
91 }

queue+struct:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 #define M(a,b) memset(a,b,sizeof(a))
 7 #define INF 0x3f3f3f3f
 8
 9 using namespace std;
10
11 int n,m;
12
13 struct node{
14    int num;
15    string c;
16 };
17 queue<node> que;
18 int can[15];
19 int vis[1000005];
20 int res;
21
22 node bfs()
23 {
24     while(!que.empty()) que.pop();
25     M(vis,0);
26     for(int i = 1;i<10;i++)
27     {
28         if(!can[i])
29         {
30             node tp;
31             tp.c = "";
32             tp.num = 0;
33             if(i%n==0) {char ch = i+‘0‘; tp.c += ch; return tp;}
34             else {
35                 tp.num = i%n;
36                 char ch = i+‘0‘;
37                 tp.c += ch;
38                 vis[i] = 1;
39                 que.push(tp);
40                 //cout<<tp.c<<endl;
41             }
42         }
43     }
44     while(!que.empty())
45     {
46         node tmp = que.front();
47         que.pop();
48         //cout<<tmp.c<<endl;
49         for(int i = 0;i<10;i++)
50         {
51             if(!can[i])
52             {
53                 int t = (tmp.num*10+i)%n;
54                 if(!vis[t])
55                  {
56                    if(t==0) {char ch = i+‘0‘; tmp.c+=ch; return tmp;}
57                    else
58                     {
59                        node tp;
60                        tp.num = t;
61                        char ch = i+‘0‘;
62                        tp.c = tmp.c+ch;
63                        //cout<<tp.num<<endl;
64                        vis[t] = 1;
65                        que.push(tp);
66                     }
67                 }
68             }
69         }
70     }
71     res = -1;
72     node none;
73     return none;
74 }
75
76 int main()
77 {
78     int cas = 1;
79     while(scanf("%d%d",&n,&m)==2)
80     {
81         res = 0;
82         M(can,0);
83         for(int i = 0;i<m;i++)
84         {
85             int a;
86             scanf("%d",&a);
87             can[a] = 1;
88         }
89         if(m==10) {printf("Case %d: -1\n",cas++); continue;}
90         node ans = bfs();
91         printf("Case %d: ",cas++);
92         if(res == -1) puts("-1");
93         else cout<<ans.c<<endl;
94     }
95     return 0;
96 }

queue+pair:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 #define M(a,b) memset(a,b,sizeof(a))
 7 #define INF 0x3f3f3f3f
 8
 9 using namespace std;
10
11 int n,m;
12
13 int can[15];
14 int vis[1000005];
15 int res;
16
17 queue<pair<string,int> > rec;
18
19 string bfs()
20 {
21     while (!rec.empty()) rec.pop();
22     pair<string,int>init;
23     init.first="";init.second=0;
24     rec.push(init);
25     int i;
26     while (!rec.empty())
27     {
28         pair<string,int> curr=rec.front();
29         for (i=0;i<10;i++)
30         {
31             if (curr.first.length()==0&&i==0) continue;
32             if (can[i]) continue;
33             char ch=‘0‘+i;
34             string ss=curr.first+ch;
35             int x=(curr.second*10+i)%n;
36             if (!vis[x])
37             {
38                 if (x==0) return ss;
39                 pair<string,int>u;
40                 u.first=ss;u.second=x;
41                 rec.push(u);
42                 vis[x]=1;
43             }
44         }
45         rec.pop();
46     }
47     return "-1";
48 }
49
50 int main()
51 {
52     int cas = 1;
53     while(scanf("%d%d",&n,&m)==2)
54     {
55         M(can,0);
56         M(vis,0);
57         for(int i = 0;i<m;i++)
58         {
59             int a;
60             scanf("%d",&a);
61             can[a] = 1;
62         }
63         string ans = bfs();
64         printf("Case %d: ",cas++);
65         cout<<ans<<endl;
66     }
67     return 0;
68 }
时间: 2024-10-20 00:38:37

2012Chhengdu K - Yet Another Multiple Problem的相关文章

HDU 4474 Yet Another Multiple Problem【2012成都regional K题】 【BFS+一个判断技巧】

Yet Another Multiple Problem Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 3407    Accepted Submission(s): 825 Problem Description There are tons of problems about integer multiples. Despit

HDOJ 4474 Yet Another Multiple Problem

BFS..... Yet Another Multiple Problem Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 3307    Accepted Submission(s): 806 Problem Description There are tons of problems about integer multiple

HDU 4474 Yet Another Multiple Problem

Yet Another Multiple Problem Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 4734    Accepted Submission(s): 1021 Problem Description There are tons of problems about integer multiples. Despit

K - Least Common Multiple

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description The least common multiple (LCM) of a set of positive integers is the smallest positive integer which is divisible by all the numbers in the set. Fo

Yet Another Multiple Problem(bfs好题)

Yet Another Multiple Problem Time Limit : 40000/20000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) Total Submission(s) : 2   Accepted Submission(s) : 1 Problem Description There are tons of problems about integer multiples. Despite the f

【暴力+BFS】HDU 4474 Yet Another Multiple Problem

通道:http://acm.hdu.edu.cn/showproblem.php?pid=4474 题意:给出n和m个数位,求一个数X,这个数是n的最小倍数且他的每一位都不含有m个数位中的任意一个. 思路:反过来想,其实就是有非M的元素组成一个数,这个数是N的倍数.如果存在解,那么他的第一位便是非M组合中的任意一位,然后除N后,他的余数便是X-a*n,那么下一位除N的就是(X-a*n)*10+(枚举的下一个非M元素),要求最小这个数,那么BFS跑最短就可以了. 代码:https://github

[bfs+余数判重+路径记录] hdu 4474 Yet Another Multiple Problem

题意: 给一个n和m个数字(一位数) 求最小的n的倍数不含有这m个数字,不存在输出-1 思路: 首先有可能这个数超long long 所以无法暴力解决 所以这题应该是一个bfs 为什么能用余数判重呢 对于当前的余数进到队列里,一定是这个余数对应数的最小值 接下来再怎么添加到满足条件的后续东西应该是一样的 所以就可以余数判重了,类似数位dp的记录方式 然后再加上一个路径记录就好了 代码: #include"cstdlib" #include"cstdio" #incl

Yet Another Multiple Problem 同余定理 bfs

题意: 给出一个n和m个数 求一个最小的数 1 为n的倍数  2 没有这m个数字中的任意一个 123%n = ((((1%n)*10+2)%n)*10+3)%n 如果     a%n==b%n 那么    (a+x)%n==(b+x)%n 这样就可以剪枝了   之前取模n出现过的后来再出现就可以不要了 例如 A%n==B%n 且 A<B 那么B就不用处理了 #include<cstdio> #include<cstring> #include<vector> #i

Regionals 2012 :: Chengdu

题目连接 排行榜 A和I都是签到题 按位BFS K Yet Another Multiple Problem 题意:给一些可以用的数字,求最小的数,它由特定的数字组成且是n的倍数 分析:暴力枚举不可行,因为数字可能非常大.考虑到大数取模为0,BFS每一层即数位,递归输出路径. #include <bits/stdc++.h> const int N = 1e4 + 5; bool no[10]; std::pair<int, int> pre[N]; int dir[10]; bo