HDU1664 BFS + 数论 + 剪枝
题目链接: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 + 数论 + 剪枝的更多相关文章
- UVA - 11882 Biggest Number(dfs+bfs+强剪枝)
题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的 ...
- hdu1664 bfs+余数判重
input n 不超过50个例子,n==0结束输入 Sample Input 7 15 16 101 0 output 最少个不同数字的n的倍数的x,若不同数字个数一样,输出最小的x Sample O ...
- soj1091 指环王 bfs+hash+剪枝
原题链接http://acm.scu.edu.cn/soj/problem.action?id=1091 这题的主要解法就是搜索,我用的是bfs,用map将二维数组处理成字符串作为主键,到达当前状态的 ...
- POJ 3278 Catch That Cow[BFS+队列+剪枝]
第一篇博客,格式惨不忍睹.首先感谢一下鼓励我写博客的大佬@Titordong其次就是感谢一群大佬激励我不断前行@Chunibyo@Tiancfq因为室友tanty强烈要求出现,附上他的名字. Catc ...
- hdu 1044(bfs+dfs+剪枝)
Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)
题目传送门 题目大意:给出n座城市,每个城市都有一个0到9的val,城市的编号是从0到n-1,从i位置出发,只能走到(i*i+1)%n这个位置,从任意起点开始,每走一步都会得到一个数字,走n-1步,会 ...
- HDU1495 非常可乐(BFS/数论)
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多.但see ...
- hdu 2717 Catch That Cow(BFS,剪枝)
题目 #include<stdio.h> #include<string.h> #include<queue> #include<algorithm> ...
- UVA-11882 bfs + dfs + 剪枝
假设当前已经到达(x,y),用bfs判断一下还可以到达的点有maxd个,如果maxd加上当前已经经过的长度小于当前答案的长度就退出,如果相同,就将bfs搜索到的点从大到小排序,如果连最大序列都无法大于 ...
随机推荐
- 对Json的一些理解
标准json格式:{"name":"王大昭","url":"https://www.cnblogs.com/codezhao/&q ...
- bootstrap常用部件下载
http://shapebootstrap.net/item/1524915-adminlte-dashboard-and-control-panel/live-demo
- 开源文字识别软件tesseract
1.下载4.0软件,下一步下一步到成功: 2.安装之后配置环境变量,Path中添加安装路径(默认:C:\Program Files (x86)\Tesseract-OCR) 3.新增语言库的环境变量, ...
- 基于 bootstrap 字体图标,用纯CSS实现星级评分功能
需要用到的图标 实现原理 关键属性是 text-overflow: clip;,表示直接截断文本.我们经常用这个属性的另一个值 text-overflow: ellipsis; 来做省略表示. 先平铺 ...
- WebAPI学习及Swagger使用
本文用来保存自己学习WebAPI和Swagger使用过程中参考的文章,以及对WebAPI的初步了解. 1.RESTful风格 WebAPI只支持Http协议: 1.1.WebAPI与MVC的区别 Va ...
- 用户与授权:MySQL系列之六
一.用户管理 1.用户账号 用户的账号由用户名和HOST俩部分组成('USERNAME'@'HOST') HOST的表示: 主机名 具体IP地址 网段/掩码 可以使用通配符表示,%和_:192.168 ...
- 使用combobox下拉列表框实现省 市 县 的三级联动
package com.hanqi.entity; //地区 public class Region { //地区id private String regionID; //地区名称 private ...
- Navicat连接MySQL数据库的一些问题与解决方案
前言 安装MySQL数据库与Navicat并不算难事,关键是怎么让他们工作花费了我整整一天的时间,最终才把弄好.遇到各种各样的问题,上网看了大量博客,发现很多博客都是直接copy或者并不能非常好的解答 ...
- 页面上AJAX调用数据
<div class="section page9" data-page='9'> <div class="global-section-wrp med ...
- python3+Appium自动化03-Appium元素检测
需要导入方法NoSuchElementException from appium import webdriver from selenium.common.exceptions import NoS ...