UVa12107 (120ms)代码

修改的地方不多,如何让代码速度更快呢?对于搜索而言,我们可以尽量的减少解答树的层数,之前我在判断dfs是否有唯一解时搜索的

深度为8后来经过优化后深度为4,这样快了许多。

// UVa 12107
// IDA* + 剪枝 
#include <cstdio> 
#include <cstring>
#include <string>  
#include <set> 
using namespace std; 

const char alpha[] = { '*', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

int c1, c2, c3, cnt, maxd; 
char str[20], ans[20];
set<string> Set; 

bool Vis() { 
  if (str[0] == '0' || str[c1] == '0' || str[c2] == '0') return false; 
  if (str[c1-1] != '*' && str[c2-1] != '*' && str[c3-1] != '*') {
    int a = str[c1-1] - '0', b = str[c2-1] - '0', c = str[c3-1] - '0';  
    return (a*b) % 10 == c; 
  }
  return true;     
}

bool Vis1() {
  int a = 0, b = 0, c = 0;  
  for (int i = 0; i < c1; ++i) 
    a = a * 10 + str[i] - '0'; 
  for (int i = c1; i < c2; ++i) 
    b = b * 10 + str[i] - '0'; 
  c = a * b; 
  for (int i = c3-1; i >= c2; --i) {
    if (!c) return false; 
    int d = c % 10; 
    c /= 10; 
    if (str[i] != '*' && str[i] - '0' != d) return false; 
  }
  if (c) return false;  
  return true; 
} 

void dfs1(int from) {
  int i;
  for (i = from; i < strlen(str); ++i) if (str[i] == '*') break; 
  if (i >= c2) {  
    if (Vis1()) ++cnt;
    return;
  } 
  for (int j = 1; j < 11; ++j) {
    char temp = str[i]; 
    str[i] = alpha[j];  
    if (Vis()) dfs1(i+1);   
    str[i] = temp; 
    if (cnt > 1) return;  
  }
}

bool better() {
  for (int i = 0; i < c3; ++i) if (str[i] != ans[i]) {
    return ans[i] == ' ' || str[i] < ans[i]; 
  }
  return false; 
} 

bool dfs(int d, int from) { 
  if (d == maxd) { 
    cnt = 0;      
    memcpy(ans, str, sizeof(ans)); 
    if (Vis()) dfs1(0); 
    return cnt == 1; 
  } 
  if (from == c3) return false; 
  for (int j = 0; j < 11; ++j) {    
    char temp = str[from]; 
    if (str[from] == alpha[j])
      if (dfs(d, from+1)) return true;  
    if (str[from] != alpha[j]) {
      str[from] = alpha[j];
      if (dfs(d+1, from+1)) return true; 
    }
    str[from] = temp; 
  }
  return false; 
}

int main() {  
  int kase = 0; 
  char a[10], b[10], c[10]; 
  while (scanf("%s", a) == 1 && a[0] != '0') {
    scanf("%s%s", b, c);
    c1 = strlen(a), c2 = strlen(a) + strlen(b), c3 = strlen(a) + strlen(b) + strlen(c); 
    memcpy(str, a, sizeof(a)); 
    strcat(str, b), strcat(str, c);
    for (int i = 0; i < c3; ++i) ans[i] = ' '; 
    char rem[20];
    memcpy(rem, str, sizeof(rem));  
    for (maxd = 0; ; ++maxd) {
      Set.clear(); 
      if (dfs(0, 0)) break;  
      memcpy(str, rem, sizeof(str)); 
    }
    printf("Case %d: ", ++kase);
    for (int i = 0; i < c1; ++i) printf("%c", ans[i]);
    printf(" ");
    for (int i = c1; i < c2; ++i) printf("%c", ans[i]);
    printf(" ");
    for (int i = c2; i < c3; ++i) printf("%c", ans[i]); 
    printf("
");  
  }
  return 0;
}
原文地址:https://www.cnblogs.com/yifeiWa/p/11134719.html