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

NOIP2010引水入城题解

2015-10-09 15:06 253 查看
点击跟博主一起玩(zuo)耍(si)

首先这道题考验的并不是代码能力而是细心程度。仔细读题,你会发现对于每一个城市,如果要建水利设施,必须存在一个与它有公共边的比它高的城市才可以。运用贪心的算法,每次选取最高的靠近湖泊的城市进行搜索,当所有的干旱城市都建有水利设施的时候停止。当所有的靠近湖泊城市都建造了输水站而还有干旱城市没有满足条件时,需要for一遍干旱城市输出多少个没有建造水利设施。

那么接下来我们来证明一下贪心的正确性。



如上图。当干旱城市需要建造水利设施时一定存在一个有公共边的比它海拔高的城市。那么当从最高点开始搜索时,保证最少能覆盖一个靠近湖泊的城市,从而减少>=1个输水站的建造。

代码如下

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
struct factory{
long l,r;
}p[501];

long n,m,map[501][501],f[501],cnt=0;

bool vis[501][501]={0},ans[501]={0};

bool comp(const factory &a,const factory &b)
{
return a.l<b.l;
}

void dfs(long x,long y,long ori)
{
vis[x][y]=1;
if(x==m){
ans[y]=1;
p[ori].l=min(p[ori].l,y);
p[ori].r=max(p[ori].r,y);
}
if(map[x+1][y]<map[x][y]&&x!=m&&!vis[x+1][y])dfs(x+1,y,ori);
if(map[x-1][y]<map[x][y]&&x!=1&&!vis[x-1][y])dfs(x-1,y,ori);
if(map[x][y+1]<map[x][y]&&y!=n&&!vis[x][y+1])dfs(x,y+1,ori);
if(map[x][y-1]<map[x][y]&&y!=1&&!vis[x][y-1])dfs(x,y-1,ori);
}

int main()
{
cin>>m>>n;
for(long i=1;i<=n;++i)p[i].l=f[i]=30000;
f[0]=0;
for(long i=1;i<=m;++i)
for(long j=1;j<=n;++j)cin>>map[i][j];
for(long i=1;i<=n;++i){
dfs(1,i,i);
memset(vis,0,sizeof(vis));
}
for(long i=1;i<=n;++i)
if(!ans[i])++cnt;
if(cnt)cout<<0<<endl<<cnt;
else{
cout<<1<<endl;
for(long i=1;i<=n;++i)
for(long j=1;j<=n;++j){
if(i>=p[j].l&&i<=p[j].r)f[i]=min(f[i],f[p[j].l-1]+1);
}
cout<<f
;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  代码 搜索