CodeForces Gym 100971J 感觉题意有问题

来源:互联网 发布:mac number 求和 编辑:程序博客网 时间:2024/05/10 23:37

为了纪念这道题,我决定贴一个特别迷的AC代码上来,纪念我那估计二十来发WA和TLE。如果有人发现我的问题了,欢迎回复或者私信,感激不尽

链接:http://codeforces.com/gym/100971/problem/J

首先这道题的意思就是, 给一个地图,#表示障碍,.表示可以走,1表示1号机器人的位置,2表示2号机器人的位置,现在想交换两个人的位置,问能否做到,

两个限制条件就是,1:在同一时刻,他们不能在同一位置,2:如果他们相邻,那他们不能直接交换位置。


然后,我的理解,首先,他没有要求两个人必须同时走,就是有人可以等,那就简单很多了,分两种情况,一种是有T字型路口的,只要两个人之间有道路通过,那么有一个 就可以躲在T字型的一端,然后让另一个人先走,然后它在走,就可以,当然这个T字型路口必须是两个人可以走到的地方。第二种情况就是没有T字型路口,就是每个点周围四个可走的点都<=2,但是有1号的点和2号的点可以连成一个环,就是有回路,然后就肯定一个人从这条路走,一个人从另一条路走,就可以了

想想假如A和B之间只有一条路可走,而且这条路中间没有分叉,B在另一端有个T字型的点,那它可以先跑到T字型的一端躲起来,然后A走过了跑到T字型的另一端躲起来,然后B去A的位置,然后A再去B的位置,就完成交换了。

假如两人本来就相邻的话, 那如果路径数>=2,那也一个人从另一条路走,然后另一个人直接走过来就可以。假如是只能直接过去但是有T字型口的话,比如T字型点在A那里,A可以先躲到T字型的一端,B躲到另一端,A走到B的位置,B走到A的位置,也就完成了

想不出还有什么特殊情况,可能是我对题意理解有错?看他们的程序,好像只判有T字型点或者路径数>=2就行,难道题目保证AB是连通的?

所以,我就只说DFS的写法,在vj上也看到有人BFS写的,没去细看。

DFS,我觉得,

首先,判断嘛,假如路径数>=2,那么要么就是回路,成环,否则的话,肯定有T字型的点,然后就可以了,反正肯定是YES,

否则的话,就是如果(路径数==1,而且在他们可达的地方有T字型的点),就是YES,否则, 就是NO。

但是,这样就一直T,,简直没救了,,附上我的一份我认为对但是一直TLE on 20的代码,而且我感觉,好像没法再优化复杂度了吧,我是用的DFS跑路径数而且遍历所以可达点的,曾试过一次DFS跑路径数,BFS遍历所有点,也TLE on 20了。

#include <cstdio>#include <iostream>#include <algorithm>#include <cmath>#include <queue>#include <cstdlib>#include <cstring>#include <vector>#include <set>using namespace std;#define ll long long#define maxn 400005const int dx[4] = { 0, 0, 1, -1 };const int dy[4] = { 1, -1, 0, 0 };int N, M;char grid[maxn];bool walk[maxn];bool vis[maxn];bool extra = false;int ax, ay, bx, by;int tmp;int sum = 0;int xx, yy;void DFS(int x, int y,bool arrive){if (sum >= 2 || (sum == 1 && extra))return;if (extra == false && vis[x*M + y] == false){vis[x*M + y] = true;tmp = 0;for (int i = 0; i < 4; ++i){xx = x + dx[i];yy = y + dy[i];if (xx >= 0 && xx < N&&yy >= 0 && yy < M&&grid[xx*M + yy] != '#'){++tmp;}}if (tmp > 2)extra = true;}if (arrive){for (int i = 0; i < 4; ++i){xx = x + dx[i];yy = y + dy[i];if (xx >= 0 && xx < N&&yy >= 0 && yy < M&&grid[xx*M + yy] != '#'&&vis[xx*M + yy] == false){//printf("%d %d\n", xx, yy);DFS(xx, yy, true);}}}else{bool flag = false;if (x == bx&&y == by){++sum;flag = true;}walk[x*M + y] = true;for (int i = 0; i < 4; ++i){xx = x + dx[i];yy = y + dy[i];if (xx >= 0 && xx < N&&yy >= 0 && yy < M&&grid[xx*M + yy] != '#'&&walk[xx*M + yy] == false){//printf("%d %d\n", xx, yy);DFS(xx, yy, flag);}}walk[x*M + y] = false;}}int main(){//freopen("input.txt", "r", stdin);//freopen("output.txt", "w", stdout);scanf("%d%d", &N, &M);for (int i = 0; i < N; ++i){scanf("%s", &grid[i*M]);for (int j = 0; j < M; ++j){if (grid[i*M + j] == '1'){ax = i; ay = j;grid[i*M + j] = '.';}else if (grid[i*M + j] == '2'){bx = i; by = j;grid[i*M + j] = '.';}}}DFS(ax, ay,false);if (sum >= 2 || (sum == 1 && extra))printf("YES\n");elseprintf("NO\n");//system("pause");//while (1);return 0;}

我不知道那个20是一组怎样的神数据,反正我把代码中的(sum == 1&&extra)都换成extra之后,就迷之AC了,,而且46ms,快的飞起,难道说只有有T字型的点就可以吗?假如从A出发有T字型的点,但是A和B直接不连通,那怎么做到交换两个人位置呢,被这题干了好久了,,,唉,又读了一遍题,也没发现问题啊。。。


然后附上一份别人的AC代码,我感觉是,迷之AC,这也能AC?没懂那个flag是什么意义
#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#include <vector>#include <string>using namespace std;#define maxn 200005int main(){//freopen("input.txt", "r", stdin);//freopen("output.txt", "w", stdout);ios_base::sync_with_stdio(NULL);cin.tie(NULL); cout.tie(NULL);int N, M;cin >> N >> M;int cnt = 0;bool flag = true;vector<string> a(N);for (int i = 0; i < N; ++i){cin >> a[i];}for (int i = 0; i < N; ++i){for (int j = 0; j < M; ++j){if (a[i][j] == '#')continue;cnt = 0;if (i != 0 && a[i - 1][j] != '#')++cnt;if (i != N - 1 && a[i + 1][j] != '#')++cnt;if (j != 0 && a[i][j - 1] != '#')++cnt;if (j != M - 1 && a[i][j + 1] != '#')++cnt;if (cnt >= 3){cout << "YES" << endl;return 0;}if (cnt == 1)flag = false;}}if (flag)cout << "YES" << endl;elsecout << "NO" << endl;//system("pause");//while (1);return 0;}


0 0
原创粉丝点击