zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    【NOIP2006T】作业调度方案
    「NOIP2012P」寻宝
    51Nod1084 矩阵取数问题 V2
    51Nod1294 修改数组
    51nod1122 机器人走方格V4
    多项式相关模板#1
    51Nod1514 美妙的序列
    Jzoj5674 香槟
    Jzoj5669 排列
    Jzoj5665 奥立卡的诗
  • 原文地址:https://www.cnblogs.com/yifeiWa/p/11134719.html
Copyright © 2011-2022 走看看