题目链接:题目详情 (pintia.cn)
题意:n*n的网格每个格子有一个高度,格子的水会向和它相邻的高度比他低的格子流动,问所有高度0的格子最多有多少水。
思路:按高度从高到低排序,按此顺序直接模拟即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int N=520;
double ans[N][N];
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
int h[N][N];
struct node{
int x,y;
int h;
}p[N*N];
bool cmp(node a,node b)
{
return a.h>b.h;
}
int main()
{
int n,m;
cin>>n>>m;
int cnt=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&p[++cnt].h);
h[i][j]=p[cnt].h;
p[cnt].x=i;
p[cnt].y=j;
ans[i][j]=m;
}
sort(p+1,p+cnt+1,cmp);
for(int i=1;i<=cnt;i++)
{
int count=0;
if(p[i].h==0) continue;
for(int j=0;j<4;j++)
{
int nx=p[i].x+dx[j],ny=p[i].y+dy[j];
if(nx>=1&&ny>=1&&ny<=n&&nx<=n&&h[nx][ny]<h[p[i].x][p[i].y])//记录水可以流的方向个数
count++;
}
if(count==0) continue;//如果当前无可流方向就直接跳过,否则会涉及到除0错误
for(int j=0;j<4;j++)
{
int nx=p[i].x+dx[j],ny=p[i].y+dy[j];
if(nx>=1&&ny>=1&&ny<=n&&nx<=n&&h[nx][ny]<h[p[i].x][p[i].y])
ans[nx][ny]+=ans[p[i].x][p[i].y]/count;
}
ans[p[i].x][p[i].y]=0;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(!h[i][j])
printf("%lf ",ans[i][j]);
else
printf("0 ");
}
printf("\n");
}
return 0;
}