Problem Address:http://cstfs.gdufs.edu.cn:8080/PKU/showproblem?problem_id=1162
周四训练的一道题,当时没有做出来。
当时也是觉得离散化可以的。
后来老师发过来解题思路,就是把坐标离散化。
之前用的是dfs结果超时,解题思路说用bfs。然后昨晚就试了一下。
调试了好久弄好了之后提交却错误了。
昨晚都快12点了,所以没再继续。
然后突然想到了离散化之后存在的问题,那就是线与面积的问题。
今天早上被蚊子咬醒,而且蚊子还一直赖着不走= =所以干脆起来开电脑。
然后改了一下,调试了几次。然后就把它A掉了。
思路:把坐标离散化。但是每个整数点要抽象成一个坐标,相邻两个点之间的线段也要抽象成一个坐标。每个整数点的坐标+mid(101)之后再乘以2然后减一得到最后的坐标。把每条线段的两个点从头到尾标记起来。最后统计面积的时候只统计偶数点位的个数。因为奇数点位都是原来整数点的位置,只有当横纵坐标都为偶数时才是一个单位的面积。然后从整个图的边缘进行bfs,如果小于水位则继续,否则返回。表示水是否可以漫过。
以下贴代码:
#include <iostream> using namespace std; const int mid = 101; const int leftpoint = (-100+mid)*2-1; const int rightpoint = (100+mid)*2-1; const int top = (-100+mid)*2-1; const int bottom = (100+mid)*2-1; int map[410][410]; bool visited[410][410]; int direction[2][8]={-1,-1,-1,0,0,1,1,1,-1,0,1,-1,1,-1,0,1}; int w; int y[200005],x[200005]; int max(int a, int b) { if (a>=b) return a; else return b; } bool check(int r, int c) { if (r<top || r>bottom || c<leftpoint || c>rightpoint) return false; if (visited[r][c]) return false; return true; } void bfs(int r, int c) { if (visited[r][c]) return; int start=0, end=1; int ty, tx, tr, tc; int i; visited[r][c] = true; if (map[r][c]>=w) return; map[r][c]=-1; y[0] = r; x[0] = c; while(end!=start) { ty = y[start]; tx = x[start]; start++; for (i=0; i<8; i++) { tr = ty+direction[0][i]; tc = tx+direction[1][i]; if (check(tr,tc)) { visited[tr][tc] = true; if (map[tr][tc]<w) { map[tr][tc] = -1; y[end] = tr; x[end] = tc; end++; } } } } } int main() { int n,x1,x2,y1,y2,h,sum; int i,j,t; scanf("%d", &n); while(scanf("%d", &n)!=EOF) { memset(map, 0, sizeof(map)); memset(visited, false, sizeof(visited)); for (i=0; i<n; i++) { scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &h); if (x1==x2) { if (y1>y2) { t = y1; y1 = y2; y2 = t; } for (j=(y1+mid)*2-1; j<=(y2+mid)*2-1; j++) map[j][(x1+mid)*2-1] = max(map[j][(x1+mid)*2-1],h); } else { if (x1>x2) { t = x1; x1 = x2; x2 = t; } for (j=(x1+mid)*2-1; j<=(x2+mid)*2-1; j++) map[(y1+mid)*2-1][j] = max(map[(y1+mid)*2-1][j],h); } } scanf("%d", &w); for (i=top; i<=bottom; i++) { bfs(i,leftpoint); bfs(i,rightpoint); } for (j=leftpoint; j<=rightpoint; j++) { bfs(top,j); bfs(bottom,j); } sum = 0; for (i=top+1; i<=bottom; i+=2) { for (j=leftpoint+1; j<=rightpoint; j+=2) { if (map[i][j]==0) sum++; } } printf("%d/n", sum); } return 0; }
长呀长呀的代码啊……
p.s.这几天感冒了,没心情学习,也没心情做题。不过现在基本都好了,所以也要好好努力了!