题意:给出一个数字谜,要求修改尽量少的数,使修改后的数字谜只有唯一解。空格和数字可以随意替换,但不能增删,数字谜中所有涉及的数必须是没有前导零的正数。输入数字谜一定形如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. pytorch 调整tensor的维度位置

    target.permute([0, 3, 1, 2]) 一定要使用permute以及中括号 一些在我这里没起到作用的网上的例子: 1. https://blog.csdn.net/zouxiaolv ...

  2. Mybatis入门(五)属性名和字段名不一致解决

    在学Mybatis的时候都需要创建一个实体类,但创建实体类的变量必须和数据库的一样,这章就来解决这个有趣的问题 目录: 问题是这样: 输出的结果是: password为空,这就很难受: 解决方法: 第 ...

  3. Day1-XDoj-1062

    题目描述 一天,lw梦见自己在打dota,然而对面是一个加强过的卡尔!于是,他每次都被n个技能瞬间秒杀.愤怒的lw决定买BKB,来加强生存力. 由于加强过的卡尔是电脑操作的,他每次看见lw时,只会以1 ...

  4. 083、Java数组之方法返回数组

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  5. Angularjs中controller的三种写法

    在Angular中,Directive.Service.Filter.Controller都是以工厂方法的方式给出,而工厂方法的参数名对应着该工厂方法依赖的Service.angularjs中cont ...

  6. k-近邻算法python代码实现(非常全)

    1.k近邻算法是学习机器学习算法最为经典和简单的算法,它是机器学习算法入门最好的算法之一,可以非常好并且快速地理解机器学习的算法的框架与应用.它是一种经典简单的分类算法,当然也可以用来解决回归问题.2 ...

  7. Centos7 静默安装 Oracle11G

    1.准备安装包: 安装包官网下载地址:https://www.oracle.com/technetwork/database/enterprise-edition/downloads/112010-l ...

  8. f_lseek

    我在STM32中移植了fatfs文件系统,实现在SD卡对文件的读写.在普通读写中都没有问题,但是一旦我关闭文件系统,再次打开读写,之前写的数据就被覆盖.比如举个例子:       u8 tx_buff ...

  9. Unbutu下装oracle

    Ubuntu 16.04安装Oracle 11gR2入门教程图文详解 转自         https://www.linuxidc.com/Linux/2017-12/149797.htm  原文作 ...

  10. Springboot注解使用总结

    使用Spring boot已经有段时间了,但是对很多注解的使用经常会遇到模糊甚至不解的地方,这次有时间便总结一下. 注解(Annotation)概念 注解是Java5开始对元数据的支持,注解与注释是有 ...