您的位置:首页 > 其它

POJ/PKU 2110

2011-10-11 21:06 183 查看
  最近好忙,好久没有更新- -水题做太多了。。。。。

  2110是一个很好的搜索题。解法就是枚举最小值,任何二分区间,再暴力bfs。直接宽搜是肯定不行的。

  看这个博客里面给的两个数据就知道了。/article/4912618.html

  然后做法就跟普通宽搜类似了,只要判断每个位置上的值是不是在区间内,如果在就加入队列。否则排除。如果是强一点的数据这样可能就超时了。但是这个题没有。所以知道出题者的想法很重要。严格来讲这样其实也是不好的= =

  所以就跟省赛的那个题一样,如果没有思路就用最朴素的算法乱搞,没准就过了。拼RP也是一件很纠结的事情。。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <string.h>
#include <set>
#include <queue>
#include <map>
#include <bitset>
#include <queue>
#include <fstream>
#include <string>
#include <algorithm>

using namespace std;

const int N = 105;
int a

, n, start, end;

struct point {
int x, y;
};

point d[N * N];
bool vis

;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

bool bfs(int u, int v) {

if (a[1][1] < u || a[1][1] > v)
return false;

memset(vis, 0, sizeof(vis));
vis[1][1] = true;
int f = 0, r = 1;
d[0].x = 1;
d[0].y = 1;

while (f < r) {

int p, q;

for (int i = 0; i < 4; i++) {

p = d[f].x + dx[i];
q = d[f].y + dy[i];

if (p < 1 || p > n || q < 1 || q > n)
continue;
if (!vis[p][q] && a[p][q] >= u && a[p][q] <= v) {

vis[p][q] = true;
d[r].x = p;
d[r++].y = q;
if (p == n && q == n) return true;
}
}

f++;
}

return false;
}

void solve() {

int l = 0, h = 110, mid, ans = 110;

while (l <= h) {

mid = (l + h) / 2;
bool flag = true;

for (int i = start; i <= end; i++)
if (bfs(i, min(i + mid, end))) {

h = mid - 1;
ans = min(ans, mid);
flag = false;
break;
}

if (flag) l = mid + 1;

}

cout << ans << endl;
}

int main() {

while (~scanf("%d", &n)) {

start = 10000;
end = 0;

for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
scanf("%d", &a[i][j]);

start = min(start, a[i][j]);
end = max(end, a[i][j]);
}

solve();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: