POJ 1465 Multiple
2016-04-10 20:09
288 查看
【题意】给了n个数字,和一个数m,其中m的范围在5000以内,现在问你能否用这n个数字拼成一个数,使得数是m的倍数,并且要保证这个数最小!
【分析】由于要最小,排序是必要的,然后就是搜索了。想了很久都不能搞定这个问题,网查大牛博客了。才发现这个题真的劲啊,用了一个同于剪枝!具体如下:
A=MX+R B=NX+R 假设A,B对于X的余数相同 那么 (10*A+d[i])%x (10*B+d[i])%x 的意义是一样的,所以只有当余数没出现过的情况下才加入到搜索的队列中来
另外还有一个问题,就是可能是最后的答案出现很庞大的位数,如果这里用高精度就太麻烦了。我用的是静态指针。还有就是单独处理N=0的情况【具体实现】知道这个剪枝就可以做这道题,可以用一个结构体维护当前这个节点的个位数,余数,以及Pre,为了输出答案,维护这个静态指针,始终指向当前节点的首位置,所以递归顺序输出就行了。vis标记当前这个节点的余数是否入队,这里当然是bfs啦。而且考虑到输出,跟上大牛博客,写成结构体数组模拟bfs,不然输出真的不好整!
【补充】这题应该属于数学知识剪枝加bfs,很劲。
【AC代码】
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 5050;
struct node{
int ge,yu,pre;
node(){}
node(int ge,int yu,int pre):ge(ge),yu(yu),pre(pre){}
}que[maxn];
int n,m;
int digit[100];
bool vis[maxn];
void print_ans(node t)
{
if(t.pre!=-1)
{
print_ans(que[t.pre]);
printf("%d",t.ge);
}
}
void bfs()
{
int head,tail,r;
memset(vis,false,sizeof(vis));
bool fuck=false;
que[0]=node(0,0,-1);
head=0,tail=1;
while(head<tail)
{
node now = que[head];
node cur;
for(int i=0;i<n;i++)
{
r=(10*now.yu+digit[i])%m;
if(!vis[r]&&(now.pre!=-1||digit[i]>0))
{
vis[r]=true;
cur.ge=digit[i];
cur.yu = r;
cur.pre = head;
que[tail++]=cur;
if(r==0)
{
fuck=true;
print_ans(cur);
printf("\n");
break;
}
}
if(fuck)break;
}
head++;
if(fuck)break;
}
if(fuck==false)
{
printf("0\n");
}
}
int main()
{
while(~scanf("%d",&m))
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&digit[i]);
sort(digit,digit+n);
if(m==0)
{
puts("0");
}
else
{
bfs();
}
}
return 0;
}
【分析】由于要最小,排序是必要的,然后就是搜索了。想了很久都不能搞定这个问题,网查大牛博客了。才发现这个题真的劲啊,用了一个同于剪枝!具体如下:
A=MX+R B=NX+R 假设A,B对于X的余数相同 那么 (10*A+d[i])%x (10*B+d[i])%x 的意义是一样的,所以只有当余数没出现过的情况下才加入到搜索的队列中来
另外还有一个问题,就是可能是最后的答案出现很庞大的位数,如果这里用高精度就太麻烦了。我用的是静态指针。还有就是单独处理N=0的情况【具体实现】知道这个剪枝就可以做这道题,可以用一个结构体维护当前这个节点的个位数,余数,以及Pre,为了输出答案,维护这个静态指针,始终指向当前节点的首位置,所以递归顺序输出就行了。vis标记当前这个节点的余数是否入队,这里当然是bfs啦。而且考虑到输出,跟上大牛博客,写成结构体数组模拟bfs,不然输出真的不好整!
【补充】这题应该属于数学知识剪枝加bfs,很劲。
【AC代码】
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 5050;
struct node{
int ge,yu,pre;
node(){}
node(int ge,int yu,int pre):ge(ge),yu(yu),pre(pre){}
}que[maxn];
int n,m;
int digit[100];
bool vis[maxn];
void print_ans(node t)
{
if(t.pre!=-1)
{
print_ans(que[t.pre]);
printf("%d",t.ge);
}
}
void bfs()
{
int head,tail,r;
memset(vis,false,sizeof(vis));
bool fuck=false;
que[0]=node(0,0,-1);
head=0,tail=1;
while(head<tail)
{
node now = que[head];
node cur;
for(int i=0;i<n;i++)
{
r=(10*now.yu+digit[i])%m;
if(!vis[r]&&(now.pre!=-1||digit[i]>0))
{
vis[r]=true;
cur.ge=digit[i];
cur.yu = r;
cur.pre = head;
que[tail++]=cur;
if(r==0)
{
fuck=true;
print_ans(cur);
printf("\n");
break;
}
}
if(fuck)break;
}
head++;
if(fuck)break;
}
if(fuck==false)
{
printf("0\n");
}
}
int main()
{
while(~scanf("%d",&m))
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&digit[i]);
sort(digit,digit+n);
if(m==0)
{
puts("0");
}
else
{
bfs();
}
}
return 0;
}
相关文章推荐
- 类似LCS,构成目标单词(POJ2192)
- 数据结构KMP算法中next函数的求解思想及其解释
- 20145317彭垚 《Java程序设计》第6周学习总结
- oracle小数点前零丢失的问题
- Swift 入门基础-2
- innodb recovery
- 【Android基础】网络图片查看器
- 简单的秒表定时器
- W3C标准与规范
- 排序问题-希尔排序
- Linux命令整合之alias
- Unity 设置Android SDK path
- SSH开发环境整合搭建
- 关于U盘启动操作系统《30天自制操作系统》
- 在编写工程注册页面中的体会和遇到的问题
- 微博API调用
- ios程序后台继续运行
- 汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp这些都是什么意思啊?
- JQuery选择器
- android之notifyDataSetChanged失效