USACO Betsy's Tour 解题报告

来源:互联网 发布:知乎top50 编辑:程序博客网 时间:2024/06/13 11:44

大神做了这道题:https://www.byvoid.com/blog/usaco-544-betsys-tour。解释得非常清楚,我也是按照这种方法做的,即统计“必经点”的个数,如果为0,则周围点都要试一遍;否则,如果为1,则选择这个必经点走;如果多余1个,则无论选择其中哪个,都会走向死胡同,所以不用再走了。只用这一个优化就可以通过所有测试点,虽然很险。

USER: chen chen [thestor1]TASK: betsyLANG: C++Compiling...Compile: OKExecuting...   Test 1: TEST OK [0.003 secs, 3500 KB]   Test 2: TEST OK [0.005 secs, 3500 KB]   Test 3: TEST OK [0.005 secs, 3500 KB]   Test 4: TEST OK [0.003 secs, 3500 KB]   Test 5: TEST OK [0.003 secs, 3500 KB]   Test 6: TEST OK [0.011 secs, 3500 KB]   Test 7: TEST OK [0.969 secs, 3500 KB]All tests OK.

Your program ('betsy') produced all correct answers! This is yoursubmission #2 for this problem. Congratulations!

网上和标准答案都是用的这个优化,只不过实现地更有效些,即用一个数组保存每个点周围的没有访问过的点的个数,并实时更新,这样不必每步都重新计算。

大神提到了另外一个优化,就是对那种“一分为二”的情况直接跳出。但我总觉得有点困惑,觉得需要判断整行或整列的情况才能得到,所以没有使用(当然,主要是测试点都过了)。

/* ID: thestor1 LANG: C++ TASK: betsy */#include <iostream>#include <fstream>#include <cmath>#include <cstdio>#include <cstring>#include <climits>#include <cassert>#include <string>#include <vector>#include <list>#include <set>#include <map>#include <queue>#include <stack>#include <algorithm>#include <cassert>using namespace std;const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};// 88418int cntfree(int r, int c, int N, std::vector<std::vector<bool> > &visited){int nr, nc;int nfree = 0;for (int d = 0; d < 4; ++d){nr = r + dx[d], nc = c + dy[d];if (nr < 0 || nr >= N || nc < 0 || nc >= N || visited[nr][nc]){continue;}nfree++;}return nfree;}void DFS(int r, int c, int N, std::vector<std::vector<bool> > &visited, int &cnt, int nvisited){if (r == N - 1 && c == 0){if (nvisited == N * N){cnt++;}return;}visited[r][c] = true;int nr, nc;int naccesspoint = 0, accessr, accessc;for (int d = 0; d < 4; ++d){nr = r + dx[d], nc = c + dy[d];if (nr < 0 || nr >= N || nc < 0 || nc >= N || visited[nr][nc] || (nr == N - 1 && nc == 0)){continue;}int nfree = cntfree(nr, nc, N, visited);if (nfree == 1){naccesspoint++;accessr = nr, accessc = nc;}}// if more than 1 access points, then there will be dead endif (naccesspoint == 0){for (int d = 0; d < 4; ++d){nr = r + dx[d], nc = c + dy[d];if (nr < 0 || nr >= N || nc < 0 || nc >= N || visited[nr][nc]){continue;}DFS(nr, nc, N, visited, cnt, nvisited + 1);}}else if (naccesspoint == 1){DFS(accessr, accessc, N, visited, cnt, nvisited + 1);}visited[r][c] = false;}int main(){ifstream fin("betsy.in");int N;fin >> N;fin.close();std::vector<std::vector<bool> > visited(N, std::vector<bool>(N, false));int cnt = 0;DFS(0, 0, N, visited, cnt, 1);ofstream fout("betsy.out");fout << cnt << endl;fout.close();return 0;  }


0 0