[itint5]直角路线遍历棋盘 - 阿牧遥 - 博客园


[itint5]直角路线遍历棋盘 - 阿牧遥 - 博客园
https://github.com/zdzapple/itint5/blob/master/%E7%9B%B4%E8%A7%92%E8%B7%AF%E7%BA%BF%E9%81%8D%E5%8E%86%E6%A3%8B%E7%9B%98.cpp
无向图的欧拉路径:只有0或者2个度数为奇数的点
欧拉回路:每个顶点的度数都是偶数
有向图的欧拉路径:起始顶点的出度(从这个顶点发出的有向边的数量)比入度(指向这个顶点的有向边的数量)多1,结束顶点的出度比入度少1,而其它顶点的出度和入度都相等。
欧拉回路:以下两个之一:
每个顶点的出度和入度都相等;
存在一系列的(有向)环,使得图里的每一条边都恰好属于某一个环。

具体的转换方式为:n,m的棋盘,建一个包含n+m个顶点的图G(为了方便说明,类似二分图将其分为两列,左边n个顶点,右边m个顶点,分别代表n行和n列)。对于目标格子(i,j),左边第i个顶点和右边第j个顶点连一条边。最后的问题其实就是问转换之后的图G是否存在欧拉欧拉回路或者欧拉路径。
证明:相邻两步为直角,其实就是从某一行变到某一列。访问图G中的一条边,意味着访问棋盘中的一个目标点。由于图G中的边只连接左边的点(代表某一行)和右边的点(代表某一列),因此访问一条边就意味着从某一行变到了某一列,也就是转直角了。
所以问题变为能否从一点出发访问G中的所有边有且仅有一次。这个就是欧拉回路问题了。

//如果存在满足条件的遍历,返回true,否则返回false
bool existPath(vector<int> &x, vector<int> &y)
{
int n = x.size();
if (x.empty())
return true;
int rowNum = x[0];
int colNum = y[0];
int i, j;
for (i = 0; i < n; ++  i)
{
if (rowNum < x[i])
rowNum = x[i];
if (colNum < y[i])
colNum = y[i];
}
// the graoh should be connected graph
//判断连通性
    bool xa[50] = {false};
    bool ya[50] = {false};
    xa[x[0]] = true;
    ya[y[0]] = true;
    i = 1, j = x.size() - 1;
    while (i <= j)
{
        if(xa[x[i]] || ya[y[i]]) {
            xa[x[i]] = true;
            ya[y[i]] = true;
            i ++;
            j = x.size() - 1;
        }
        else {
            int xt = x[j], yt = y[j];
            x[j] = x[i];
            y[j] = y[i];
            x[i] = xt;
            y[i]= yt;
            j--;
        }
    }
    if (i!=x.size())
return false;


// the number of odd degresses should be 0 or 2
vector<int> leftDegress(rowNum + 1, 0);
vector<int> rightDegress(colNum + 1, 0);
for (i = 0; i < n; ++ i)
{
leftDegress[x[i]] ++;
rightDegress[y[i]] ++;
}
int oddDegressCount = 0;
for (i = 0; i <= rowNum; ++ i)
{
if (leftDegress[i] % 2)
oddDegressCount ++;
}
for (i = 0; i <= colNum; ++ i)
{
if (rightDegress[i] % 2)
oddDegressCount ++;
}
return oddDegressCount == 0 || oddDegressCount == 2;
}

这题一开始直接用暴力的DFS来做,果然到25的规模就挂了.
vector<bool> visited(50, false);
vector<vector<int> > vec_row(50);
vector<vector<int> > vec_col(50);
 
bool findPath(vector<int> &x, vector<int> &y, int idx, int depth, int direction) {
    if (depth == x.size()) return true;
    visited[idx] = true;
    if (direction == 0) {
        int row = x[idx];
        for (int i = 0; i < vec_row[row].size(); i++) {
            if (!visited[vec_row[row][i]]) {
                if (findPath(x, y, vec_row[row][i], depth+1, 1))
                    return true;
            }
        }
    else {
        int col = y[idx];
        for (int i = 0; i < vec_col[col].size(); i++) {
            if (!visited[vec_col[col][i]]) {
                if (findPath(x, y, vec_col[col][i], depth+1, 0))
                    return true;
            }
        }
    }
     
    visited[idx] = false;
    return false;
}
 
 
//如果存在满足条件的遍历,返回true,否则返回false
bool existPath(vector<int> &x, vector<int> &y) {
    int k = x.size();
    if (k == 0) return true;
    for (int i = 0; i < k; i++) {
        vec_row[x[i]].push_back(i);
        vec_col[y[i]].push_back(i);
    }
    for (int i = 0; i < k; i++) {
        if (findPath(x, y, i, 1, 0) ||
            findPath(x, y, i, 1, 1)) {
                return true;
            }
    }
    return false;
}

这题可以直接转换为欧拉回路(路径)问题,这样,如果有解的时候要输出遍历路径的时候,也比较好办了。
具体的转换方式为:n,m的棋盘,建一个包含n+m个顶点的图G(为了方便说明,类似二分图将其分为两列,左边n个顶点,右边m个顶点,分别代表n行和n列)。对于目标格子(i,j),左边第i个顶点和右边第j个顶点连一条边。最后的问题其实就是问转换之后的图G是否存在欧拉欧拉回路或者欧拉路径。
证明:相邻两步为直角,其实就是从某一行变到某一列。访问图G中的一条边,意味着访问棋盘中的一个目标点。由于图G中的边只连接左边的点(代表某一行)和右边的点(代表某一列),因此访问一条边就意味着从某一行变到了某一列,也就是转直角了。
所以问题变为能否从一点出发访问G中的所有边有且仅有一次。这个就是欧拉回路问题了。
 所以欧拉路径是:1.连通;2.奇点为2,为0时是欧拉回路。
 这里的连通我用并查集来做。注意写并查集的merge时,要先找到根,再merge。
vector<int> djset;
 
int find(int i) {
    int x = i;
    while (djset[x] != x) {
        x = djset[x];
    }
    djset[i] = x;
    return x;
}
 
void merge(int i, int j) {
    djset[find(i)] = djset[find(j)];
}
 
//如果存在满足条件的遍历,返回true,否则返回false
bool existPath(vector<int> &x, vector<int> &y) {
    vector<int> axis(100, 0);
    // 计算奇点数目
    for (int i = 0; i < x.size(); i++) {
        axis[x[i]] = !axis[x[i]]; // 奇偶变换
    }
    for (int i = 0; i < y.size(); i++) {
        axis[y[i]+50] = !axis[y[i]+50];
    }
    int count = 0;
    for (int i = 0; i < axis.size(); i++) {
        if (axis[i]) count++;
    }
    if (count != 0 && count != 2) return false;
     
    djset.resize(x.size());
    for (int i = 0; i < djset.size(); i++) {
        djset[i] = i;
    }
     
    // 判断连通性
    for (int i = 0; i < x.size(); i++) {
        for (int j = i+1; j < x.size(); j++) {
            if (x[i] == x[j]) {
                merge(i, j);
            }
        }
    }
    for (int i = 0; i < y.size(); i++) {
        for (int j = i+1; j < y.size(); j++) {
            if (y[i] == y[j]) {
                merge(i, j);
            }
        }
    }
     
    for (int i = 0; i < x.size(); i++) {
        if (find(i) != find(0)) {
            return false;
        }
    }
    return true;
}
Read full article from [itint5]直角路线遍历棋盘 - 阿牧遥 - 博客园

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts