HDU4394 Digital Square【分支限界法BnB】
2016-08-12 10:16
323 查看
Digital Square
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2062 Accepted Submission(s): 830
[align=left]Problem Description[/align]
Given an integer N,you should come up with the minimumnonnegative integer M.M meets the follow condition: M2%10x=N (x=0,1,2,3....)
[align=left]Input[/align]
The first line has an integer T( T< = 1000), the number of test cases.
For each case, each line contains one integer N(0<= N <=109), indicating the given number.
[align=left]Output[/align]
For each case output the answer if it exists, otherwise print “None”.
[align=left]Sample Input[/align]
3
3
21
25
[align=left]Sample Output[/align]
None
11
5
[align=left]Source[/align]
2012 Multi-University Training Contest 10
问题链接:HDU4394 Digital Square。
题意简述:
输入测试用例数量t,输入t个正整数n,求最小的m,满足m^2%10^x=n,其中k=0,1,2,...。
问题分析:
x是不定的,用暴力法试探m是不现实的。有关模除%的问题,可以用从低位开始逐步试探的方法,即先试探个位,然后十位、百位、千位等等。已知n的情况下,m的低位是有限的。例如n=21,那么m的个位只能是1或9,其他的数字是无法满足给定条件的。解决本问题需要明确以下几点:
1.对于m,从最低位开始试探,m的每位的数字可以是0-9,这时匹配n的最低位;
2.试探完1位再试探2位、3位和4位等等,分别匹配n的最低1位、2位、3位和4位等等;
3.m起始值:0,1,2,3,......;
4.显式剪枝条件:低位不匹配;
5.LC函数(优先函数):为了找到最小的满足条件的m,低位匹配的m中,值最小的节点优先展开。
程序说明:
节点node的成员变量说明如下:
curr:当前低位匹配的m值;
len:当前已经匹配的位数;
digit:当前位正在试探的数字(0-9)。
题记:
分支限界法有三种策略,分别是FIFO、LIFO和LC(least cost)。BFS属于分支限界法的一种,通常采用FIFO策略,采用LIFO策略的情况比较少见,因为多数情况下这两种策略效果几乎相同。分支限界法采用LC策略时,通常用BFS+优先队列来实现。
AC的C++语言程序如下:
/* HDU4394 Digital Square */ #include <iostream> #include <queue> using namespace std; typedef unsigned long long ULL; const int MAXN = 18; const int MAXDIGIT = 9; struct node { ULL curr; int len, digit; node(){} node(ULL c, int l, int n):curr(c), len(l), digit(n){} bool operator<(const node n) const { return curr > n.curr; } }; node start; int n; ULL fact[18]; int nlen; ULL ans; void bfs() { nlen = 0; ULL temp = n; while(temp) { nlen++; temp /= 10; } ans = 0; priority_queue<node> q; q.push(node(0, 0, 0)); while(!q.empty()) { node top = q.top(); q.pop(); if(top.len == nlen) { ans = top.curr; break; } else if(top.digit != MAXDIGIT) q.push(node(top.curr, top.len, top.digit+1)); node v; v.curr = top.curr + fact[top.len] * top.digit; v.len = top.len + 1; v.digit = 0; if(v.curr * v.curr % fact[v.len] == n % fact[v.len]) q.push(v); } } int main() { int t; fact[0] = 1; for(int i=1; i<MAXN; i++) fact[i] = fact[i-1] * 10; cin >> t; while(t--) { cin >> n; bfs(); if(ans) printf("%llu\n", ans); else printf("None\n"); } return 0; }
相关文章推荐
- 神经网络基础
- Codeforces Round #367 (Div. 2)
- webservice中WSDL文档的解析
- 推理集 —— 逻辑
- JS模拟数据去重汇总
- mysql 安装
- 图结构练习——判断给定图是否存在合法拓扑序列
- 黑客入侵里约政府官网抗议奥运:比赛会伤害城市
- 网页在Safari快速滚动和回弹的原理: -webkit-overflow-scrolling : touch;的实现
- C#连接Oracle数据库(直接引用dll使用)
- Docker简介
- 神经网络学习的原理与在OpenCV中的应用
- elasticsearch源码分析之客户端(三)
- 算法导论之用于不相交集合的数据结构
- 使用函数的得墨忒耳法则来解耦
- Android Telephony分析(七) ---- 接口扩展(异步转同步)
- 去除数字里多余的零
- angularjs --- ngResource 类似于 ajax发送请求。
- ASP.NET Core 中文文档 第三章 原理(10)依赖注入
- java中编码方式的总结