您的位置:首页 > 编程语言 > Go语言

TYVJ 2009「Poetize8」Lagoon

2016-07-10 22:58 447 查看


描述

忘川沧月的小水塘的水面是一片由以下两种图形组成的图案:


 <图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 TEST
printf("{%d, %d}.get()!\n", x, y);
#endif
const 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 TEST
printf("getting in (%d, %d) type %d!\n", p.x, p.y, p.t);
#endif
for(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ BFS