引水入城
Posted zhinv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了引水入城相关的知识,希望对你有一定的参考价值。
引水入城
- BFS + 贪心
贪心还能用递归写!
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int,int> pii;
const int MAXN=500+1,MAXM=500+1;
int h[MAXN][MAXM], vis[MAXN][MAXM], cover[MAXM],in[MAXM];
struct Seq
{
int l,r;
Seq(){l=r=0;}
bool operator < (const Seq& s)const{return l<s.l;}
} s[MAXM];
queue<pii>q;
void bfs(int Y,int n,int m,int& cnt)
{
const int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
memset(vis, 0, sizeof(vis));
int L = 1000, R = -1;
q.push(pii {1, Y});
vis[1][Y]=1;
while(!q.empty())
{
pii u = q.front();
q.pop();
int x = u.first, y = u.second;
if(x==n){L=min(y,L);R=max(y,R);cover[y]=1;}
for(int i=0,a,b; i<4; i++)
{
a=x+dx[i];b=y+dy[i];
if(a>=1 && a<=n && b>=1 && b<=m && h[a][b]<h[x][y] && !vis[a][b])
{
q.push(pii {a, b});
vis[a][b]=1;
}
}
}
if (L >= 1 && L <= m && R >= 1 && R <= m && L<=R)
{
s[++cnt].l = L;
s[cnt].r = R;
}
}
int dfs(int i,int n, int L, int R,bool& is)
{
if (s[i].l>L)
{
is = false;
return 0;
}
if (s[i].r >= R) return 1;
int x = i + 1, r = s[x].r;
for (int j = i + 2; j <= n && s[j].l <= s[i].r+1; j++)
if (s[j].r > r) r = s[x = j].r;
return 1 + dfs(x, n, s[x].r + 1, R, is);
}
int main()
{
memset(h,-1,sizeof(h));
memset(cover,0,sizeof(cover));
int n,m;
scanf("%d %d",&n,&m);
for(int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &h[i][j]);
int cnt = 0;
for (int i = 1; i <= m; i++)
if(h[1][i]>=h[1][i-1] && h[1][i]>=h[1][i+1])
bfs(i, n, m, cnt);
if (!cnt)
{
cout << 0 << endl << m;
return 0;
}
int num = 0;
for(int i = 1;i <= m; i++)
if(!cover[i])num++;
if(num)
{
cout<< 0 << endl << num;
return 0;
}
sort(s + 1, s+cnt + 1);
bool is = true;
int start = 0, r = -1, ans = 0;
for (int i = 1; s[i].l == 1 && i <= m; i++)
if (s[i].r > r) r = s[start = i].r;
ans = dfs(start, cnt, 1, m, is);
cout<< 1 << endl << ans;
return 0;
}
(Question:)
为什么这么写不对呢?
void bfs(int Y,int n,int m,int& cnt)
{
const int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
memset(vis, 0, sizeof(vis));
int L = 1000, R = -1;
q.push(pii {1, Y});
vis[1][Y] = 1;
while(!q.empty())
{
pii u = q.front();
q.pop();
int x = u.first, y = u.second;
if(x==n)
{
if (y < L) L = y;
if (y > R) R = y;
}
if(x==1)in[y]=true;
for(int i=0; i<4; i++)
{
int a=x+dx[i],b=y+dy[i];
if(a>=1 && a<=n && b>=1 && b<=m)
{
if(h[a][b]<h[x][y]&&!vis[a][b])
{
q.push(pii {a, b});
vis[a][b] = 1;
}
}
}
}
if (L >= 1 && L <= m && R >= 1 && R <= m && L <= R)
{
s[++cnt].l = L;
s[cnt].r = R;
}
}
然后主函数里这样:
for(int i=1; i<=cnt; i++)
{
for(int j=s[i].l;j<=s[i].r;j++)
cover[j]=1;
}
int num = 0;
for(int i = 1;i <= m; i++)
if(!cover[i])num++;
if(num)
{
cout<< 0 << endl << num;
return 0;
}
(???)留着以后解决吧
以上是关于引水入城的主要内容,如果未能解决你的问题,请参考以下文章