题意:给出一个数字谜,要求修改尽量少的数,使修改后的数字谜只有唯一解。空格和数字可以随意替换,但不能增删,数字谜中所有涉及的数必须是没有前导零的正数。输入数字谜一定形如a*b=c,其中a、b、c分别最多有2、2、4位。
分析:

1、因为输出字典序最小,所以每一位数按“*0123456789”顺序枚举。

2、如果当前要修改的数与即将被修改的数相同,则cnt不加1。

3、检查积的时候,为防超时,只枚举两个乘数,通过检查积的位数和积的已确定数字来验证。

4、遇到空格要跳过并检查返回结果。

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {, -, , , -, -, , };
const int dc[] = {-, , , , -, , -, };
const int MOD = 1e9 + ;
const double pi = acos(-1.0);
const double eps = 1e-;
const int MAXN = + ;
const int MAXT = + ;
using namespace std;
string s;
map<int, pair<int, int> > mp;//3个字符串的起始终止下标
const string ss = "*0123456789";
int maxn;
int len;
int num;
int changetodigit(string t){
int l = t.size();
int ans = ;
for(int i = ; i < l; ++i){
ans = ans * + t[i] - '';
}
return ans;
}
bool check(){//检查积是否合法
int x = changetodigit(s.substr(mp[].first, mp[].second - mp[].first + ));
int y = changetodigit(s.substr(mp[].first, mp[].second - mp[].first + ));
char str[];
sprintf(str, "%d", x * y);
int l = strlen(str);
if(mp[].second - mp[].first + != l) return false;//位数不相同
for(int i = mp[].first; i <= mp[].second; ++i){
if(s[i] == '*') continue;
if(s[i] != str[i - mp[].first]) return false;
}
return true;
}
bool leadingzero(int cur){//判断当前下标是否为数字的第一位
for(int i = ; i < ; ++i){
if(mp[i].first == cur) return true;
}
return false;
}
void judge(int cur){
if(num > ) return;
if(cur == mp[].second + ){
if(check()) ++num;
return;
}
if(s[cur] != '*') judge(cur + );
else{
for(int i = ; i < ; ++i){
if(i == && leadingzero(cur)) continue;
s[cur] = ss[i];
judge(cur + );
s[cur] = '*';
}
}
}
bool dfs(int cnt, int cur){
if(cnt >= maxn){
string tmp = s;
num = ;
judge();
s = tmp;
if(num == ){
return true;
}
return false;
}
if(cur == len) return false;
if(s[cur] == ' '){
if(dfs(cnt, cur + )) return true;
return false;
}
else{
char c = s[cur];
for(int i = ; i < ; ++i){
if(i == && leadingzero(cur)) continue;
if(c == ss[i]){//如果当前要修改的数与即将被修改的数相同
if(dfs(cnt, cur + )) return true;
}
else{
s[cur] = ss[i];
if(dfs(cnt + , cur + )) return true;
s[cur] = c;
}
}
return false;
}
}
int main(){
int kase = ;
while(getline(cin, s)){
if(s[] == '') return ;
len = s.size();
int cnt = ;
int st = ;
for(int i = ; i < len; ++i){
if(s[i] == ' '){
mp[cnt++] = pair<int, int>(st, i - );
st = i + ;
}
}
mp[cnt++] = pair<int, int>(st, len - );
printf("Case %d: ", ++kase);
for(maxn = ; ; ++maxn){
if(dfs(, )){
printf("%s\n", s.c_str());
break;
}
}
}
return ;
}

UVA - 12107 Digit Puzzle(数字谜)(IDA*)的更多相关文章

  1. UVA_Digit Puzzle UVA 12107

    If you hide some digits in an integer equation, you create a digit puzzle. The figure below shows tw ...

  2. UVa 1225 Digit Counting --- 水题

    UVa 1225 题目大意:把前n(n<=10000)个整数顺次写在一起,12345678910111213...,数一数0-9各出现多少字 解题思路:用一个cnt数组记录0-9这10个数字出现 ...

  3. UVa 1583 Digit Generator --- 水题+打表

    UVa 1583 题目大意:如果x加上x的各个数字之和得到y,那么称x是y的生成元. 给定数字n,求它的最小生成元 解题思路:可以利用打表的方法,提前计算出以i为生成元的数,设为d,并保存在a[d]中 ...

  4. 紫书 习题7-8 UVa 12107 (IDA*)

    参考了这哥们的博客 https://blog.csdn.net/hyqsblog/article/details/46980287  (1)atoi可以char数组转int, 头文件 cstdlib ...

  5. UVA - 1343 The Rotation Game (BFS/IDA*)

    题目链接 紫书例题. 首先附上我第一次bfs+剪枝TLE的版本: #include<bits/stdc++.h> using namespace std; typedef long lon ...

  6. UVa 1583 Digit Generator(数学)

     题意 假设a加上a全部数位上的数等于b时 a称为b的generator  求给定数的最小generator 给的数n是小于100,000的  考虑到全部数位和最大的数99,999的数位和也才45 ...

  7. UVa 10533 - Digit Primes

    题目:输出给定区间中,本身是素数,而且这个数的各位之和也是素数的数(称为位素数)的个数. 分析:数论.首先利用筛法,求出1000000内的全部的素数:然后在利用生成的素数表, 推断每一个数是不是各位之 ...

  8. UVa 1343 旋转游戏(dfs+IDA*)

    https://vjudge.net/problem/UVA-1343 题意:如图所示,一共有8个1,8个2和8个3,如何以最少的移动来使得中间8个格子都为同一个数. 思路:状态空间搜索问题. 用ID ...

  9. UVa 11212 编辑书稿(dfs+IDA*)

    https://vjudge.net/problem/UVA-11212 题意:给出n个自然段组成的文章,将他们排列成1,2...,n.每次只能剪切一段连续的自然段,粘贴时按照顺序粘贴. 思路:状态空 ...

随机推荐

  1. SpringMVC--文件上传与下载

    http://blog.csdn.net/u012706811/article/details/51059419

  2. Linux开机流程及运行级别

    启动流程: 没有运行程序的硬件除了会电人,没有别的用处.那么计算机是如何识别软件并执行的呢?下面介绍操作系统的开机启动流程: BIOS:开机时主动执行的第一个程序,会识别存储设备. MBR:第一个可开 ...

  3. Maven是什么,如何使用Maven

    一.简单的小问题? 1.1.假如你正在Eclipse下开发两个Java项目,姑且把它们称为A.B,其中A项目中的一些功能依赖于B项目中的某些类,那么如何维系这种依赖关系的呢? 很简单,这不就是跟我们之 ...

  4. 014、MySQL取本月天数(这个月有多少天)

    #取本月天数 SELECT DATEDIFF( date_add( curdate( ) , INTERVAL MONTH ), DATE_ADD( curdate( ), INTERVAL DAY ...

  5. 面试-PA和XSYX面试小结

    XSYX 1.自我介绍 2. 最近一个项目的业务和技术栈 3. 分布式锁解决库存问题 4. spring的IOC和AOP讲解 5. 类加载器层级 6.线程池核心参数和问题 7. 期待的团队是怎样的? ...

  6. python矩阵运算大全(linalg模块)

    python矩阵的运算大全 python矩阵运算可以用numpy模块,也可以用scipy模块,主要运算包括以下几种: #1-1python矩阵运算所需模块 import numpy as npimpo ...

  7. P1429 平面最近点对(加强版)(分治)

    P1429 平面最近点对(加强版) 主要思路: 分治,将点按横坐标为第1关键字升序排列,纵坐标为第2关键字升序排列,进入左半边和右半边进行分治. 设d为左右半边的最小点对值.然后以mid这个点为中心, ...

  8. Golang的单目(一元)运算符-地址操作符和接收操作符

    Golang的单目(一元)运算符-地址操作符和接收操作符 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Golang的单目(一元)运算符概述 常见的地址操作符: &: ...

  9. DNS原理和智能DNS及CDN

    CDN是什么 CDN(Content Delivery Network)是内容分发网络. 作用: 使用户可以就近取的所需要的内容,加速用户访问网站资源的速度.物理距离更近,响应速度更快.拦截部分网络请 ...

  10. Docker常用命令,Docker安装Nginx、Redis、Jenkins、tomcat、MySQL

    常用命令 拉取镜像:docker pull xxx启动镜像:docker run --name xxx 8080:8080 -d xxx查看容器:docker ps xxx 停止容器:docker s ...