noip2010引水入城

https://www.zybuluo.com/ysner/note/1334997

这道题fst了

题面

戳我

解析

我一开始的想法是,按照高度给第一行排序,然后贪心地选取目前到不了的,高度最高的第一行的点来\(DFS\),一旦满足题目要求就退出。
但是这样有问题,只有\(40pts\)
因为高度越高,不一定代表能走的越远。

有一个在考场上不一定能想到的结论:当可以满足所有位置的时候,在每个位置建立蓄水场,那么它影响的范围一定是一段连续区间
这个证还是很好证:如果中间被隔开了,那么中间那个点就不可能被影响了,因为它所在的不被影响的块被可以被影响的部分完全包围,这都影响不到就没办法了。

然后问题转化为覆盖整段区间所需要的线段数。
在判定可行后,把所有区间按左端点排序,贪心地选取即可。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;++i)
#define fq(i,a,b) for(re int i=a;i>=b;--i)
using namespace std;
const int N=600;
int n,m,w[N][N],ans,mx[4]={1,-1,0,0},my[4]={0,0,1,-1},tot;
bool vis[N][N],ok[N];
struct dat{int l,r;il bool operator < (const dat &o) const {return l<o.l;}}a[N];
il ll gi()
{
  re ll x=0,t=1;
  re char ch=getchar();
  while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  if(ch=='-') t=-1,ch=getchar();
  while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  return x*t;
}
il void DFS(re int x,re int y)
{
  vis[x][y]=1;
  fp(i,0,3)
    {
      re int xx=x+mx[i],yy=y+my[i];
      if(xx<1||xx>n||yy<1||yy>m||vis[xx][yy]||w[xx][yy]>=w[x][y]) continue;
      DFS(xx,yy);
    }
}
int main()
{
  n=gi();m=gi();
  fp(i,1,n)
      fp(j,1,m) w[i][j]=gi();
  fp(i,1,m)
    {
      DFS(1,i);
      fp(j,1,m)
    {
      if(!vis[n][j-1]&&vis[n][j]) a[i].l=j;
      if(vis[n][j]&&!vis[n][j+1]) a[i].r=j;
      ok[j]|=vis[n][j];
    }
      memset(vis,0,sizeof(vis));
    }
  fp(i,1,m) if(!ok[i]) ++tot;
  if(tot) return printf("0\n%d\n",tot),0;
  sort(a+1,a+1+m);
  re int mxr=0,i=1;
  while(!a[i].l&&i<=m) ++i;
  for(re int j=i;i<=m&&mxr<m;i=j)
    {
      re int now=mxr;
      while(a[j].l<=mxr+1&&j<=m) now=max(now,a[j++].r);
      ++ans;mxr=now;
    }
  printf("1\n%d\n",ans);
  return 0;
}

转载于:https://www.cnblogs.com/yanshannan/p/9920915.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2010年全国青少年信息学奥林匹克联赛(NOIP)提高组的复赛是一次重要的比赛。在这次比赛中,参赛选手需要展示出在信息学方面的专业知识和技能。 比赛的复赛共有两个题目,分别是算法设计题和程序设计题。算法设计题要求选手设计一个高效的算法来解决特定的问题,参赛选手需要对问题进行深入分析,找到最佳的解决方案。程序设计题要求选手根据题目要求,使用编程语言编写出能够正确解决问题的程序。 在比赛中,选手们需要在限定的时间内完成这两个题目。时间限制会对选手的应试能力和抗压能力提出要求。选手需要利用自己所学的知识和经验,灵活地运用在实际的问题中,制定出最佳的解决方案。 在复赛中,评委们会根据选手的算法设计和程序设计的质量来进行评判。他们会考察选手的算法思路是否清晰,是否能通过代码来实现自己的想法。评委们还会参考选手的编码风格,包括代码的可读性和规范性。这些综合因素将影响选手在比赛中的表现。 参加2010年NOIP提高组的复赛对于选手们来说是一次难得的机会。这次比赛既能测试选手们的能力和水平,也能提供一个展示自己的舞台。在这个比赛中,选手们需要充分发挥自己的优势,努力争取好的成绩,并从中积累经验,提高自己的编程能力和解决问题的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值