您的位置:首页 > 其它

HDOJ 4474 Yet Another Multiple Problem(BFS + 剪枝)

2014-10-21 01:02 477 查看
给你一个数n,在不能用某些数字的情况下找到能表示成n的倍数的最小值,如果不能表示输出-1。

首先模运算的规则:

A % N == B % N  → A*K % N == B*K % N → (A + C) % N == (B + C) % N → (A*K + C) % N == (B*K + C)
% N

→ (A*10 + C) % N == (B*10 + C) % N

所以可以用bfs搜索,从数字最小的情况搜起。每次只需保存余数,和最先出现这个余数时,记录添加在末尾的那位数字,一旦遇到余数为0,则将记录中的数字逆序输出。

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>

using namespace std;

const int maxn = 10010;
int n, m, x;
bool dig[10];
int pre[maxn], save[maxn];
queue<int> q;

void put(int u)
{
if(pre[u] != -1)
put(pre[u]);
printf("%d", save[u]);
}

void bfs()
{
while(!q.empty())
q.pop();
int rema, now;
for(int i = 1; i <= 9; i++)
{
if(!dig[i])
{
rema = i % n;
if(rema == 0)
{
printf("%d", i);
return ;
}
q.push(rema);
save[rema] = i;
}
}
while(!q.empty())
{
now = q.front();
q.pop();
for(int i = 0; i <= 9; i++)
{
if(!dig[i])
{
rema = (now * 10 + i) % n;
if(save[rema] == -1)
{
q.push(rema);
pre[rema] = now;
save[rema] = i;
}
if(rema == 0)
{
put(rema);
return ;
}
}
}
}
printf("-1");
}

int main()
{
int cas = 0;
while(~scanf("%d%d", &n, &m))
{
printf("Case %d: ", ++cas);
memset(dig, false, sizeof(dig));
memset(pre, -1, sizeof(pre));
memset(save, -1, sizeof(save));
for(int i = 0; i < m; i++)
{
scanf("%d", &x);
dig[x] = true;
}
bfs();
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: