1. 程式人生 > >UVA12107-Digit Puzzle(叠代加深搜索)

UVA12107-Digit Puzzle(叠代加深搜索)

pac als strlen string sin using != 字典序 spa

Problem UVA12107-Digit Puzzle

Accept:85 Submit:612

Time Limit: 3000 mSec

技術分享圖片 Problem Description

技術分享圖片

技術分享圖片 Input

The input contains several test cases. Each test case contains three non-empty strings, x, y, z, having at most 2, 2 and 4 characters respectively. Each character is a digit or a wildcard ‘*’, x will not begin with a zero character. The last test case is followed by a single zero, which should not be processed.

技術分享圖片 Output

For each test case, print the case number and the converted puzzle. If more than one optimal solution is found, the lexicographically ?rst one should be printed (remember that “*” is before “0”). There is always a solution.

技術分享圖片 Sample Input

7 ** 8* ** ** *** 0

技術分享圖片 Sample Ouput

Case 1: 7 ** 8*

Case 2: ** ** 1*

題解:題目思路不難,實現起來略顯困難。用IDA*控制修改個數,用另一個dfs函數判斷解是否可行,在這裏稱為check。字典序很簡單,就是搜的時候從小到大就行,第一個找到的答案肯定字典序最小。

由於最後輸出的是待填空的字符串,因此在check的過程中,臨時修改的全局變量一定要記得改回來。由於必須是唯一解才是最終的可行解,因此check函數在編寫的過程中,絕不能找到一組解就return true.

記錄解的組數,大於1就break,改回全局變量之後return cnt.

 1 #include <bits/stdc++.h>
 2 
 3 using
namespace std; 4 5 const char table[] = "*0123456789"; 6 const int maxn = 10; 7 8 int maxd; 9 int len[3]; 10 char s[maxn][maxn]; 11 12 int cal() { 13 int aa = atoi(s[0]), bb = atoi(s[1]); 14 int cc = aa * bb; 15 char tmp[maxn]; 16 for (int i = 0; i < len[2];i++) { 17 tmp[len[2] - i - 1] = cc % 10 + 0; 18 cc /= 10; 19 } 20 if (cc != 0 || tmp[0] == 0) return 0; 21 22 for (int i = 0; i < len[2]; i++) { 23 if (s[2][i] != *) { 24 if (s[2][i] != tmp[i]) return 0; 25 } 26 } 27 return 1; 28 } 29 30 int check(int id, int pos) { 31 if (id == 2) return cal(); 32 33 int ta, tb, cnt = 0; 34 if (pos == len[id] - 1) ta = id + 1, tb = 0; 35 else ta = id, tb = pos + 1; 36 37 char t = s[id][pos]; 38 if (isdigit(s[id][pos])) { 39 cnt += check(ta, tb); 40 } 41 else { 42 for (int i = 1; i < 11; i++) { 43 if (i == 1 && pos == 0) continue; 44 s[id][pos] = table[i]; 45 cnt += check(ta, tb); 46 if (cnt > 1) break; 47 } 48 } 49 50 s[id][pos] = t; 51 return cnt; 52 } 53 54 bool dfs(int d, int id, int pos) { 55 if (d == maxd) return check(0, 0) == 1; 56 if (id == 3) return false; 57 58 int ta, tb; 59 if (pos == len[id] - 1) ta = id + 1, tb = 0; 60 else ta = id, tb = pos + 1; 61 62 char t = s[id][pos]; 63 for (int i = 0; i < 11; i++) { 64 if (i == 1 && pos == 0) continue; 65 if (s[id][pos] == table[i]) { 66 if (dfs(d, ta, tb)) return true; 67 } 68 else { 69 s[id][pos] = table[i]; 70 if (dfs(d + 1, ta, tb)) return true; 71 s[id][pos] = t; 72 } 73 } 74 75 return false; 76 } 77 78 int main() 79 { 80 int iCase = 1; 81 while (~scanf("%s", s[0])) { 82 if (s[0][0] == 0) break; 83 scanf("%s%s", s[1], s[2]); 84 for (int i = 0; i < 3; i++) { 85 len[i] = strlen(s[i]); 86 } 87 88 for (maxd = 0;; maxd++) { 89 if (dfs(0, 0, 0)) break; 90 } 91 92 printf("Case %d: ", iCase++); 93 printf("%s %s %s\n", s[0], s[1], s[2]); 94 } 95 return 0; 96 }

UVA12107-Digit Puzzle(叠代加深搜索)