http://acm.split.hdu.edu.cn/showproblem.php?pid=4474
题目大意:
给一个数n 求n的最小倍数 倍数要求不含有给出的m个数
分析:
bfs按位搜索 没加剪枝T 看了下题解 同余模定理 例如 123%n = ((((1%n)*10+2)%n)*10+3)%n
如果 a%n==b%n
那么 (a+x)%n==(b+x)%n
这样就可以剪枝了 之前取模n出现过的后来再出现就可以不要了
AC代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include<list>
#include <bitset>
#include <climits>
#include <algorithm>
#define gcd(a,b) __gcd(a,b)
#define mset(a,n) memset(a,n,sizeof(a))
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
typedef long long LL;
const LL mod=1e9+7;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
using namespace std;
int n,m;
bool vis[10];
struct node{
int pre;
int num;
}a[10005];
void Output(int tt){
if (a[tt].pre!=-1) Output(a[tt].pre);
printf ("%d",a[tt].num);
}
void bfs(){
queue<int> Q;
for (int i=1;i<=9;i++){
if (!vis[i]){
int tt=i%n;
if (tt==0){
printf ("%d",i);
return;
}
Q.push(tt);
a[tt].num=i;
}
}
while (!Q.empty()){
int temp=Q.front();Q.pop();
for (int i=0;i<=9;i++){
if (!vis[i]){
int tt=(temp*10+i)%n;
if (a[tt].num==-1){
Q.push(tt);
a[tt].pre=temp;// 记录前驱
a[tt].num=i;// 记录本位数字
}
if (tt==0){
Output(tt);
return ;
}
}
}
}
printf ("-1");
}
int main (){
int cc=1;
while (scanf ("%d%d",&n,&m)!=EOF){
int x;
mset(vis,0);mset(a,-1);
for (int i=0;i<m;i++){
scanf ("%d",&x);
vis[x]=1;
}
printf ("Case %d: ",cc++);
bfs();putchar('\n');
}
return 0;
}