UVa 12107 数字谜(Digit Puzzle)

注释写的很清楚了
加深迭代搜索
双重搜索
超级暴力。。

#include<bits/stdc++.h>
#define LL long long
using namespace std;
string s[3];
char ch[] = "*0123456789";
int len[3];

bool cal() {
	// 核对
	int num1, num2, num3;
	num1 = stoi(s[0]);
	num2 = stoi(s[1]);
	num3 = num1 * num2;
	char buf[10];
	sprintf(buf, "%d", num3);
	string ss = buf;
	if (ss.length() != len[2]) return false;
	for (int i = 0; i < len[2]; i++) {
		if (s[2][i] != ss[i] && s[2][i] != '*') {
			return false;
		}
	}
	return true;
}

int check(int id, int pos) {
	//保证在 id = 0,1 填满数字 
	if (id == 2) return cal();
	int cnt = 0;
	char store = s[id][pos];
	//下一步
	int ta, tb;
	if (len[id] == pos + 1) {
		ta = id + 1;
		tb = 0;
	}
	else {
		ta = id;
		tb = pos + 1;
	}

	if (isdigit(store)) {
		cnt += check(ta, tb);
	}
	else {
		for (int i = 1; i < 11; i++) {
			if (i == 1 && pos == 0) continue;
			s[id][pos] = ch[i];
			cnt += check(ta, tb);
			if (cnt > 1) break;
		}
	}
	s[id][pos] = store;
	return cnt;
}

//修改原先的字符串
//d代表当前深度 maxd代表搜索到的深度 id代表是哪一个字符串
//一共有三个字符串 s[0] * s[1] = s[2
//pos代表某个字符串的位置
bool dfs(int d, int maxd, int id, int pos) {
	if (d == maxd) {
		return check(0, 0) == 1;
	}
	if (id == 3) return false;
	//保留原先字符
	char store = s[id][pos];

	//下一步
	int ta, tb;
	if (len[id] == pos + 1) {
		ta = id + 1;
		tb = 0;
	}
	else {
		ta = id;
		tb = pos + 1;
	}

	for (int i = 0; i < 11; i++) {
		//除去前导零
		if (i == 1 && pos == 0) continue;
		//如果一样的话 没必要替换 不消耗替换次数
		if (s[id][pos] == ch[i]) {
			if (dfs(d, maxd, ta, tb)) return true;
		}
		else {
			s[id][pos] = ch[i];
			if (dfs(d + 1, maxd, ta, tb)) return true;
			//回溯
			s[id][pos] = store;
		}
	}
	return false;
}

int main() {
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	while (cin >> s[0]) {
		if (s[0][0] == '0') break;
		cin >> s[1] >> s[2];
		len[0] = s[0].length();
		len[1] = s[1].length();
		len[2] = s[2].length();
		int maxd;
		//IDA* 加深迭代搜索
		for (maxd = 0; ; maxd++) {
			if (dfs(0, maxd, 0, 0)) break;
		}
		cout << s[0] << " " << s[1] << " " << s[2] << " " << endl;
	}
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值