zoukankan      html  css  js  c++  java
  • hihoCoder#1054 滑动解锁

    原题地址

    回溯搜索

    对于每个待枚举的点,检查:

    1. 度数检查:是否违反了出度入度限制。因为生成的路径除了首尾节点外,其他节点的出度和入度只能为2

    2. 共线检查:是否违反了共线条件。即跨越了尚未枚举过的节点

    对于枚举产生的路径,检查:

    1. 长度检查:长度是否大于等于4

    2. 完整性检查:是否包含了片段中出现的所有边

    代码:

      1 #include <iostream>
      2 #include <cstring>
      3 
      4 using namespace std;
      5 
      6 int impossible[100];
      7 
      8 bool integrity_check(int piece[9][9], int path[9][9]) {
      9   for (int i = 0; i < 9; i++)
     10     for (int j = 0; j < 9; j++)
     11         if (piece[i][j] && !path[i][j])
     12           return false;
     13   return true;
     14 }
     15 
     16 bool degree_check(int piece[9][9], int path[9][9], int b, int e) {
     17   if (piece[b][e])
     18     return true;
     19 
     20   int bdegree = 0;
     21   int edegree = 0;
     22 
     23   for (int i = 0; i < 9; i++) {
     24     bdegree += path[b][i] || piece[b][i] ? 1 : 0;
     25     edegree += path[e][i] || piece[e][i] ? 1 : 0;
     26   }
     27 
     28   return bdegree < 2 && edegree < 2;
     29 }
     30 
     31 bool collineation_check(int visited[9], int b, int e) {
     32   int t = (b + 1) * 10 + e + 1;
     33   return impossible[t] < 0 || visited[impossible[t] - 1];
     34 }
     35 
     36 bool check(int piece[9][9], int path[9][9], int visited[9], int b, int e) {
     37   if (visited[e])
     38     return false;
     39 
     40   return degree_check(piece, path, b, e) && collineation_check(visited, b, e);
     41 }
     42 
     43 int search(int piece[9][9], int path[9][9], int visited[9], int p, int len) {
     44   int res = 0;
     45 
     46   if (len >= 4 && integrity_check(piece, path))
     47     res++;
     48 
     49   for (int i = 0; i < 9 && len < 9; i++) {
     50     if (check(piece, path, visited, p, i)) {
     51       visited[i] = 1;
     52       path[p][i] = path[i][p] = 1;
     53       res += search(piece, path, visited, i, len + 1);
     54       path[p][i] = path[i][p] = 0;
     55       visited[i] = 0;
     56     }
     57   }
     58 
     59   return res;
     60 }
     61 
     62 int main() {
     63   int T;
     64   memset(impossible, -1, sizeof(int) * 100);
     65   impossible[13] = 2;
     66   impossible[46] = 5;
     67   impossible[79] = 8;
     68   impossible[17]= 4;
     69   impossible[28]= 5;
     70   impossible[39]= 6;
     71   impossible[19]= 5;
     72   impossible[37]= 5;
     73   impossible[31]= 2;
     74   impossible[64]= 5;
     75   impossible[97]= 8;
     76   impossible[71]= 4;
     77   impossible[82]= 5;
     78   impossible[93]= 6;
     79   impossible[91]= 5;
     80   impossible[73]= 5;
     81 
     82   cin >> T;
     83   while (T--) {
     84     int N;
     85     int piece[9][9] = {{0, 0}};
     86     int path[9][9] = {{0, 0}};
     87     int visited[9] = {0};
     88     int res = 0;
     89 
     90     cin >> N;
     91     for (int i = 0; i < N; i++) {
     92       int a, b;
     93       cin >> a >> b;
     94       piece[a - 1][b - 1] = piece[b - 1][a - 1] = 1;
     95     }
     96 
     97     for (int i = 0; i < 9; i++) {
     98       visited[i] = 1;
     99       res += search(piece, path, visited, i, 1);
    100       visited[i] = 0;
    101     }
    102 
    103     cout << res << endl;
    104   }
    105   return 0;
    106 }
  • 相关阅读:
    FLEX,图标操作,xml, 通信,实例
    FLEX 合并两个XML的属性
    在内核中如何获得系统的日期和时间
    delphi中生成空格的函数
    Delphi中使用@取函数地址的问题
    vc中产生随机数
    delphi里label显示多行文本的两种方法
    360,傲游,诺顿最新版,网页溢出防护原理
    VC使用Zlib对内存流进行压缩与解压缩
    【TXPManifest控件】Delphi使用XP样式的按钮等控件
  • 原文地址:https://www.cnblogs.com/boring09/p/4375554.html
Copyright © 2011-2022 走看看