1. 程式人生 > >Usaco Training [1.3] wormhole

Usaco Training [1.3] wormhole

傳送門

解題要素:程式碼能力

解題步驟:理解題意 - 》搜尋列舉所有可能的配對情況 - 》判斷衝突並求解 - 》除錯

 

一. 理解題意

  這裡講幾個不容易理解的點:

    1. +x方向 即向右走

    2. 一旦來到蟲洞,就必須掉入

二. 搜尋列舉所有可能的配對情況 

  考慮引入match陣列,對於當前的節點來說,列舉後面的點是否已配對過即可

 1 int match[N];
 2 inline void dfs(int x) { //當前節點
 3     if (x == n + 1) {
 4         rep(i, 1
, n) if (check(i, i, 1, 0)) { 5 ans++; 6 break; 7 } 8 return; 9 } 10 if (match[x]) dfs(x + 1); //已有匹配,無需列舉 11 else { 12 rep(i, x + 1, n) if (!match[i]) { //列舉 13 match[i] = x, match[x] = i; 14 dfs(x + 1); 15 match[i] = match[x] = 0
; //回溯 16 } 17 } 18 }

三. 判斷衝突並求解

  程式碼的核心部分,分析當前的一個狀態有哪些量是相關的,加上對於題目的理解

 1 int ans;
 2 inline bool check(int begin, int now, int length, int state) { //state - 0 : walk 1 : worm
 3     if (length > 1 && now == begin && state == 0) return 1; //回到原點了,而且是用走的方式
 4     if
(state == 0) { //走到蟲洞口了就跳進去 5 check(begin, match[now], length + 1, 1); 6 } 7 else { //從蟲洞d出來,就往前走,如果前面有蟲洞,就走過去,沒有就返回0 8 if (a[now].y == a[now + 1].y) check(begin, now + 1, length + 1, 0); else return 0; 9 } 10 }

 

四. 除錯

  1.讀入的座標軸是與正常的行列相反的,在排序和判同行時須格外注意

  2.因為奶牛所在初始蟲洞處時便掉進去,所以最終只有可能到蟲洞處

 

最終的程式碼:

 1 /*
 2 PROG: wormhole
 3 LANG: C++
 4 */
 5 #include <bits/stdc++.h>
 6 using namespace std;
 7 #define rep(i, a, b) for(int i = a; i <= b; ++i)
 8 
 9 const int N = 20;
10 
11 int n;
12 struct node {
13     int x, y;
14 }a[N];
15 
16 bool cmp(const node &a, const node &b) {
17     return a.y == b.y ? a.x < b.x : a.y < b.y;
18 }
19 
20 int match[N], ans;
21 
22 inline bool check(int begin, int now, int length, int state) { //state - 0 : walk 1 : worm
23     if (length > 1 && now == begin && state == 0) return 1;
24     if (state == 0) { 
25         check(begin, match[now], length + 1, 1);
26     }
27     else {
28         if (a[now].y == a[now + 1].y) check(begin, now + 1, length + 1, 0); else return 0;    
29     }
30 }
31 
32 inline void dfs(int x) {
33     if (x == n + 1) {
34         rep(i, 1, n) if (check(i, i, 1, 0)) {
35             ans++;
36             break;
37         }
38         return;
39     }
40     if (match[x]) dfs(x + 1);
41     else {
42         rep(i, x + 1, n) if (!match[i]) {
43             match[i] = x, match[x] = i;
44             dfs(x + 1);
45             match[i] = match[x] = 0;    
46         }
47     }
48 }
49 
50 int main() {
51     freopen("wormhole.in", "r", stdin);
52     freopen("wormhole.out", "w", stdout);
53     scanf("%d", &n);
54     rep(i, 1, n) {
55         scanf("%d%d", &a[i].x, &a[i].y);
56     }
57     sort(a + 1, a + n + 1, cmp);
58     dfs(1);
59     printf("%d\n", ans);
60     return 0;
61 }