TYVJ 2009「Poetize8」Lagoon

来源:互联网 发布:昆山编程培训要多久 编辑:程序博客网 时间:2024/06/09 22:02

描述

忘川沧月的小水塘的水面是一片由以下两种图形组成的图案:
 <图lagoon-1>
这两种图形都由一个边长为2的正方形和两个半径为1的1/4圆组成,圆心在正方形的两个对角顶点上。
小水塘左上角坐标为(0,0),右下角坐标为(2*n,2*m)。水面上每一个顶点坐标为偶数的2*2正方形,都是上面两个图形中的一种。如果我们往水塘中的某个位置倒一桶污水,那么这桶污水会像画图中的油漆桶一样扩散开来,占据一片连续的区域,但是在线条边界处会停止扩散。注意如果倒在了线条上,扩散面积为0。
如下图所示,就是一个由4行4列上述图形组成的、左上角坐标(0,0)、右下角坐标(8,8)、某些位置倒了污水的水塘(白色部分为线条边界,线条实际宽度认为是0,为了明显、美观,此处加粗显示):
 <图lagoon-2>
现在给出一个n行m列的由上述两种图形组成的水塘,起初水塘中全部为净水。给定q个往某个坐标上(x,y)倾倒污水的操作,对于每次操作,请求出在(x,y)上倾倒的污水最终会扩散多大的面积。


输入格式

第一行两个整数n、m。
接下来n行每行m个整数,每个整数是0或者1,中间没有空格隔开。0代表此处是<图lagoon-1>中左侧那个2*2的图形,1代表此处是右侧那个图形。例如<图lagoon-2>中的第一行用“0001”表示。
第n+2行是一个整数q。
接下来q行每行两个用空格隔开的整数x、y,表示这一次倾倒污水的坐标。


输出格式

对于每个询问,输出此次倾倒的污水最终扩散的面积,四舍五入保留4位小数。

测试样例1

输入

样例输入1
1 2
01
4
0 0
2 0
0 1
0 2

样例输入2
3 1
1
0
1
2
3 1
4 2

输出

样例输出1
0.7854
4.8584
0.0000
4.8584

样例输出2
7.2876
1.5708

备注

对于 100% 的数据,1<=n,m,q<=100,0<=x<=2*n,0<=y<=2*m。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

BFS遍历一遍,要用数组记录可能的情况。

思路说起来很简单,但是情况好多写起来好麻烦的。

我的写了180行······丑到不能看······写完的时候才想起来可以用数组记录······好方······

(下面是神犇GZZ的代码)

#include <cstdio>#include <cmath>#include <queue>#include <cstring>#include <vector>using std::queue;using std::vector;const int maxnm=100+5;int map[maxnm][maxnm];struct Size {int x;//1*1正方形个数 int y;//1/4圆个数 Size(int x, int y): x(x), y(y) {}inline Size operator +(const Size &b) const{Size r(x+b.x, y+b.y);return r;}inline double get(){#ifdef TESTprintf("{%d, %d}.get()!\n", x, y);#endifconst double pi=acos(-1.0);return x*1.0+y*pi*0.25;}};Size dw[3]={Size(0, 1), Size(4, -2), Size(0, 1)};bool vis[maxnm][maxnm][3];//某地砖某位置是否被vis了...QAQ struct Pos {int x, y;//所在地砖坐标int t;//所在位置类型 Pos(int x, int y, int t): x(x), y(y), t(t) { } };int pace[4][2]={{-1, 0}, {0, -1}, {1, 0}, {0, 1}};int turn[2][4][2][3]={{//0->...//0{{1, 2, -1}, {0, 1, -1}}, //1{{1, 2, -1}, {2, 1, -1}}, //2{{-1, 0, 1}, {-1, 1, 2}}, //3{{-1, 0, 1}, {-1, 1, 0}}},{//1->...//0{{-1, 1, 2}, {-1, 0, 1}},//1{{2, 1, -1}, {1, 2, -1}},//2{{0, 1, -1}, {1, 2, -1}},//3{{-1, 1, 0}, {-1, 0, 1}}}};int have[2][4]= {{0, 1, 1, 2},{1, 2, 0, 1}};int n, m;inline Size bfs(const vector<Pos> &st){memset(vis, 0, sizeof(vis));Size ans(0, 0);queue<Pos> q;for(int i=0; i<(signed int)st.size(); ++i){if(st[i].x<1 || st[i].x>n || st[i].y<1 || st[i].y>m) continue;q.push(st[i]);vis[st[i].x][st[i].y][st[i].t]=true;ans=ans+dw[st[i].t];}while(!q.empty()){Pos p=q.front(); q.pop();#ifdef TESTprintf("getting in (%d, %d) type %d!\n", p.x, p.y, p.t);#endiffor(int k=0; k<4; ++k){int x1=p.x+pace[k][0], y1=p.y+pace[k][1];if(x1<1 || x1>n || y1<1 || y1>m) continue;int tu=turn[map[p.x][p.y]][k][map[x1][y1]][p.t];if(tu==-1 || vis[x1][y1][tu]) continue;ans=ans+dw[tu];vis[x1][y1][tu]=true;q.push(Pos(x1, y1, tu));}}return ans;}char t_str[maxnm];int main(){//freopen("flooding.in", "r", stdin);//freopen("flooding.out", "w", stdout);scanf("%d%d", &n, &m);for(int i=1; i<=n; ++i){scanf("%s", t_str+1);for(int j=1; j<=m; ++j) map[i][j]=t_str[j]-'0';}int q; scanf("%d", &q);while(q--){int x, y; scanf("%d%d", &x, &y);vector<Pos> v;if((x&1) && (y&1)){v.push_back(Pos((x>>1)+1, (y>>1)+1, 1));}else if((x&1) || (y&1)){puts("0.0000");continue;}else{v.push_back(Pos(x>>1, y>>1, have[map[x>>1][y>>1]][3]));v.push_back(Pos(x>>1, (y>>1)+1, have[map[x>>1][(y>>1)+1]][2]));v.push_back(Pos((x>>1)+1, y>>1, have[map[(x>>1)+1][y>>1]][1]));v.push_back(Pos((x>>1)+1, (y>>1)+1, have[map[(x>>1)+1][(y>>1)+1]][0]));}printf("%.4f\n", bfs(v).get());}return 0;}


1 0
原创粉丝点击