zoukankan      html  css  js  c++  java
  • Atcoder 2444

    题面传送门

    (mxi) 为 IOI 国海拔的最大值,(mni) 为 IOI 国海拔的最小值,(mxj) 为 JOI 国海拔的最大值,(mnj) 为 JOI 国海拔的最小值。
    不难发现 (mxi,mni,mxj,mnj) 中有 2 个值已经确定下来了,(max(mxi,mxj)) 一定等于矩阵的全局最大值 (mx)(min(mni,mnj)) 一定等于矩阵的全局最小值 (mn)
    如果我们把海拔最高和最低的点分配到了同一个国家中,答案即为 (mx-mn)
    如果我们把海拔最高和最低的点分配到了不同的国家中,我们不妨假设海拔最高的点分配到了 JOI 国,海拔最低的点分配到了 IOI 国。
    二分答案。
    假设二分到 (mid),那么所有 IOI 国的城市的海拔 (leq mn+mid),所有 JOI 国的城市的海拔 (geq mx-mid)
    也就是所有海拔 (>mn+mid) 的城市全部属于 JOI 国,所有海拔 (<mx-mid) 的城市全部属于 IOI 国。
    此时题目转化为:已知某些点属于 IOI 国,某些点属于 JOI 国,判断是否存在一种合法的分配方案。
    根据题意两国的地形一定呈阶梯分部。所以可以分出四种情况,这里以 JOI 国占据左上角,IOI 国占据右下角为例。
    考虑第 (i) 两国之间的分界线 (b_i),那么一定有 (b_i leq b_{i-1}),而第 (i)(b_i) 左边肯定都是 JOI 国的城市,第 (i) 行右边肯定都是 IOI 国的城市,根据这个你可以求出 (b_i) 的最大值和最小值,然后判断是否有交集即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=2e3+5;
    int n,m,a[MAXN][MAXN],mx=0,mn=0x3f3f3f3f;
    int l[MAXN],r[MAXN];
    bool check(int mid){
    	memset(l,0,sizeof(l));memset(r,0,sizeof(r));r[0]=m+1;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]>mn+mid) l[i]=max(l[i],j);
    	for(int i=n;i;i--) l[i]=max(l[i],l[i+1]);
    	for(int i=1;i<=n;i++) r[i]=m+1;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]<mx-mid) r[i]=min(r[i],j);
    	for(int i=1;i<=n;i++) r[i]=min(r[i-1],r[i]);
    	bool flg=1;for(int i=1;i<=n;i++) flg&=(l[i]<r[i]);if(flg) return 1;
    	memset(l,0,sizeof(l));memset(r,0,sizeof(r));r[n+1]=m+1;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]>mn+mid) l[i]=max(l[i],j);
    	for(int i=1;i<=n;i++) l[i]=max(l[i],l[i-1]);
    	for(int i=1;i<=n;i++) r[i]=m+1;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]<mx-mid) r[i]=min(r[i],j);
    	for(int i=n;i;i--) r[i]=min(r[i+1],r[i]);
    	flg=1;for(int i=1;i<=n;i++) flg&=(l[i]<r[i]);if(flg) return 1;
    	memset(l,0,sizeof(l));memset(r,0,sizeof(r));r[0]=m+1;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]<mx-mid) l[i]=max(l[i],j);
    	for(int i=n;i;i--) l[i]=max(l[i],l[i+1]);
    	for(int i=1;i<=n;i++) r[i]=m+1;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]>mn+mid) r[i]=min(r[i],j);
    	for(int i=1;i<=n;i++) r[i]=min(r[i-1],r[i]);
    	flg=1;for(int i=1;i<=n;i++) flg&=(l[i]<r[i]);if(flg) return 1;
    	memset(l,0,sizeof(l));memset(r,0,sizeof(r));r[n+1]=m+1;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]<mx-mid) l[i]=max(l[i],j);
    	for(int i=1;i<=n;i++) l[i]=max(l[i],l[i-1]);
    	for(int i=1;i<=n;i++) r[i]=m+1;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]>mn+mid) r[i]=min(r[i],j);
    	for(int i=n;i;i--) r[i]=min(r[i+1],r[i]);
    	flg=1;for(int i=1;i<=n;i++) flg&=(l[i]<r[i]);if(flg) return 1;
    	return 0;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) mx=max(mx,a[i][j]),mn=min(mn,a[i][j]);
    	int l=0,r=mx-mn-1,ans=mx-mn;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if(check(mid)) ans=mid,r=mid-1;
    		else l=mid+1;
    	} printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    测试EF6.1.3和OrmLite性能
    MVC自定义分页(附表跳转页Loading提示)
    仿京东手机充值进度导航
    PTA(Advanced Level)1052.Linked List Sorting.
    用双指针法巧解——PTA(Advanced Level)1032.Sharing
    PTA(Advanced Level)1022.Digital Library
    PTA(Advanced Level)1071.Speech Patterns
    PTA(Advanced Level)1054.The Dominant Color
    PTA(Advanced Level)1100.Mars Numbers
    PTA(Advanced Level)1060.Are They Equal
  • 原文地址:https://www.cnblogs.com/ET2006/p/Atcoder-2444.html
Copyright © 2011-2022 走看看