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 ≤ 104). 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
Source
2012 Asia Chengdu Regional Contest
Recommend
liuyiding
題目分析:接觸到這道題目時,我和隊友們想的暴力一倍倍的加上去,然後加個卡時,結果一遍又一遍的逾時、wrong answer,現在想想,覺得當時好傻,非常不理智。
這題的主要思想是bfs,將可以使用的數字按字典序最小的順序bfs,直到搜出能整除n的數。裸bfs的話無疑會逾時的,我們發現,n是小於10000的,
也就是說對n取餘後的數也是小於10000的,這方面是否可以做點文章呢,其實,如果兩個數對n取餘的餘數是一樣的話,那個大一點的數完全沒有考慮的必要了,則可以用一個bool型數組記錄所得的餘數,這樣擴充的節點大概是10000左右,效率大幅度提高,174ms AC,題目給的20000ms太浪費了,呵呵。
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>struct{ int r; //當前節點的餘數 int f; //當前節點的父指標 char c;//當前節點餘數的最後一位} q[10005],tmp;void print(int k){ if (q[k].f!=-1) { print(q[k].f); } printf ("%c",q[k].c);}int main(){ int n,m,x,l,r,res,i; bool vis[10],p[10005]; int CASE=1; while (~scanf("%d%d",&n,&m)) { memset(vis,true,sizeof(vis)); while (m--) { scanf("%d",&x); vis[x]=false; } l=1; r=0; res=0; memset(p,false,sizeof(p)); for (i=1;i<10;i++) if (vis[i]&& !p[i%n]) { r++; p[i%n]=true; q[r].c=i+'0'; q[r].r=i%n; q[r].f=-1; if (i%n==0) { res=r; break; } } while (l<=r&& !res) { for (i=0;i<10;i++) if (vis[i]) { tmp.c=i+'0'; tmp.r=(q[l].r*10+i)%n; tmp.f=l; if (!p[tmp.r]) { r++; q[r]=tmp; p[tmp.r]=true; if (tmp.r==0) { res=r; break; } } } l++; } if (! res) printf("Case %d: -1\n",CASE++); else { printf("Case %d: ",CASE++); print(res); printf("\n"); } } return 0;}