题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1664 , 一道比较蛋疼的搜索题。

  这道题有很多坑点,一点处理不好就要TLE。


  题意很简单,就是找到一个n的倍数m,要求m里包含的不同数字最少。

  做这道题要有数论的知识:对于任意的整数n,必然存在一个由不多于两个的数来组成的一个倍数。

  所以这里就比较好入手了,就是先搜一个数的情况,没找到的话再搜两个数的情况。

具体解法:

  用BFS来搜索,注意要有两个剪枝:如果当前队列里的结点的字符串的长度要比已经得到的结果的最小长度要长,则退出这次搜索;只有搜到的结点的数模n的余数未出现过,该节点才能入队,不然的话就会造成重复。还有不能在结点里直接保存字符串,所以要用一个前向指针来标记,需要得到字符串的时候进行一遍递归即可。

  用一个结构体来保存结点信息:当前结点模n的余数、前向指针、结点的字符、到该结点的字符串长度。由于数据量比较大,所以要自己手动维护一个队列。

  还有要注意的是,用string生成字符串的时候,ans = c + ans要比ans += c慢很多。

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = + ;
bool vis[maxn];
int MinLen , n , a[];
struct Node {
char ch;
int mod , len , pre; //余数 , 当前长度 , 前指针
} u , v , que[maxn];
string ans , curans; void GetStr(int k) { //用递归来得到字符串信息,注意这里的写法
if(k == -) return;
GetStr(que[k].pre);
curans += que[k].ch;
}
bool cmp(string a , string b) { //比较两个串表示的十进制的大小
if(a.size() > b.size()) return true;
if(a.size() == b.size() && a > b) return true;
return false;
}
bool bfs(int k)
{
memset(vis , , sizeof(vis));
int head = , tail = -; //队列的首尾指针
for(int i = ; i <= k ; i++) {
if(a[i] != ) { //这里是保证第一个数字不为0
u.pre = -;
u.ch = a[i] + '';
u.mod = a[i] % n;
u.len = ;
vis[u.mod] = ;
que[++tail] = u;
}
}
while(head <= tail) {
u = que[head];
if(u.len > MinLen) break; //这里有一个剪枝
for(int i = ; i <= k ; i++) {
v.mod = (u.mod * + a[i]) % n;
v.ch = a[i] + '';
v.len = u.len + ;
v.pre = head;
if(!vis[v.mod]) { //同余判重
que[++tail] = v;
vis[v.mod] = ;
if(v.mod == ) { //搜到了结果
curans = "";
GetStr(tail); //获得字符串
return true;
}
}
}
head++;
}
return false;
}
int main()
{
while(~scanf("%d" , &n) && n)
{
if(n <= ) {
cout << n << endl;
continue;
}
bool flag = false;
MinLen = maxn;
ans = "";
for(int i = ; i <= ; i++) {
a[] = i;
if(bfs()) {
if(!flag || cmp(ans , curans)) {
flag = true;
ans = curans;
MinLen = ans.size();
}
}
}
if(flag) {
cout << ans << endl;
continue;
}
for(int i = ; i <= ; i++) {
for(int j = i + ; j <= ; j++) {
a[] = i; a[] = j;
if(bfs()) {
if(!flag || cmp(ans , curans)) {
flag = true;
ans = curans;
MinLen = ans.size();
}
}
}
}
cout << ans << endl;
}
return ;
}

HDU1664 BFS + 数论 + 剪枝的更多相关文章

  1. UVA - 11882 Biggest Number(dfs+bfs+强剪枝)

    题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的 ...

  2. hdu1664 bfs+余数判重

    input n 不超过50个例子,n==0结束输入 Sample Input 7 15 16 101 0 output 最少个不同数字的n的倍数的x,若不同数字个数一样,输出最小的x Sample O ...

  3. soj1091 指环王 bfs+hash+剪枝

    原题链接http://acm.scu.edu.cn/soj/problem.action?id=1091 这题的主要解法就是搜索,我用的是bfs,用map将二维数组处理成字符串作为主键,到达当前状态的 ...

  4. POJ 3278 Catch That Cow[BFS+队列+剪枝]

    第一篇博客,格式惨不忍睹.首先感谢一下鼓励我写博客的大佬@Titordong其次就是感谢一群大佬激励我不断前行@Chunibyo@Tiancfq因为室友tanty强烈要求出现,附上他的名字. Catc ...

  5. hdu 1044(bfs+dfs+剪枝)

    Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  6. hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)

    题目传送门 题目大意:给出n座城市,每个城市都有一个0到9的val,城市的编号是从0到n-1,从i位置出发,只能走到(i*i+1)%n这个位置,从任意起点开始,每走一步都会得到一个数字,走n-1步,会 ...

  7. HDU1495 非常可乐(BFS/数论)

    大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多.但see ...

  8. hdu 2717 Catch That Cow(BFS,剪枝)

    题目 #include<stdio.h> #include<string.h> #include<queue> #include<algorithm> ...

  9. UVA-11882 bfs + dfs + 剪枝

    假设当前已经到达(x,y),用bfs判断一下还可以到达的点有maxd个,如果maxd加上当前已经经过的长度小于当前答案的长度就退出,如果相同,就将bfs搜索到的点从大到小排序,如果连最大序列都无法大于 ...

随机推荐

  1. 创建、配置Servlet

    1.创建Servlet 2.选择继承的类及需要覆盖的方法 3.Servlet结构 package com.sysker.servlet; import java.io.IOException; imp ...

  2. sqoop 安装与命令

    1. 下载:   wget http://mirrors.shu.edu.cn/apache/sqoop/1.4.7/sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz 2. 解 ...

  3. loj#6053. 简单的函数(Min_25筛)

    传送门 题解 \(Min\_25\)筛有毒啊--肝了一个下午才看懂是个什么东西-- \(zsy\)巨巨强无敌-- //minamoto #include<bits/stdc++.h> #d ...

  4. SQL 日期函数转换

    1.转换函数 与date操作关系最大的就是两个转换函数:to_date(),to_char() to_date() 作用将字符类型按一定格式转化为日期类型: 具体用法:to_date('2004-11 ...

  5. JMETER CSS JQUERY EXTRACTOR

    我想如果你在这里,你可能已经访问了我们关于变量提取的JMeter系列: XPath Extractor:使用XPath Expressions从XML响应中提取内容, Regexp Extractor ...

  6. DHCP原理和配置

    在大型网络中,会有大量的主机和设备需要获取ip地址和网络参数,为了解决手动配置的工作量大.ip冲突问题,因此需要使用DHCP(dynamic host configuration protocol). ...

  7. 1105 Spiral Matrix(25 分)

    This time your job is to fill a sequence of N positive integers into a spiral matrix in non-increasi ...

  8. onbeforeunload与onunload事件

    Onunload,onbeforeunload都是在刷新或关闭时调用,可以在<script>脚本中通过 window.onunload来指定或者在<body>里指定.区别在于o ...

  9. 020 Valid Parentheses 有效的括号

    给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效.括号必须以正确的顺序关闭,"()" 和 "()[]{}" 是有效的 ...

  10. OpenStack Weekly Meeting 2015.07.17

    Reviews(Company) 1 Mirantis 11562 HP 1653 Huawei 15 Reviews(Persons) 1 Ekaterina Chernova ✻ 2852 Kir ...