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

    最近在使用 Flask 中使用 SQLAlchemy  开发程序,一开始好好的,然后使用 uWSGI 部署到线上后,出现了各种 mysql 客户端的问题,如: (_mysql_exceptions.P ...

  2. JAVA实现单例模式的四种方法和一些特点

    JAVA实现单例模式的四种方法和一些特点,需要的朋友可以参考一下     一.饿汉式单例类 复制代码 代码如下: public class Singleton  {      private Sing ...

  3. HDU 1024:Max Sum Plus Plus 经典动态规划之最大M子段和

    Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  4. shell教程——bash入门

    创建shell文件 vim test.sh 写内容 #!/bin/bash echo "Hello World !" 使脚本具有执行权限 chmod +x ./test.sh 执行 ...

  5. Python实现的远程登录windows系统功能示例

    https://www.jb51.net/article/142326.htm 重点是这几本书要好好读读!: 更多关于Python相关内容感兴趣的读者可查看本站专题:<Python进程与线程操作 ...

  6. PL/SQL 找到某列都为空的列名

    DECLARE CURSOR temp IS SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE TABLE_NAME=Upper('xxx'); v_num ...

  7. python面试总结知识点

    1.python中is和==的区别 Python中对象包含的三个基本要素,分别是:id(身份标识) .type(数据类型)和value(值). ‘==’比较的是value值 ‘is’比较的是id 2. ...

  8. ubuntu18.04下安装oh-my-zsh

    安装 sudo apt-get install zsh wget --no-check-certificate https://github.com/robbyrussell/oh-my-zsh/ra ...

  9. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-play-circle

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  10. Linux netfliter 架构

    netfliter 简介 netfilter是在Linux 2.4.X内核引入的一个子系统,它提供了一个抽象的.通用框架,这个框架提供了一整套的钩子函数的管理机制.包括钩子函数的原型定义,注册,注销等 ...