zoukankan      html  css  js  c++  java
  • AT2444 JOIOI 王国 (Kingdom of JOIOI)

    洛咕

    双倍经验

    题意:给定n行m列的矩阵,每个格子是一个有权值的小方块.将矩阵分成两个部分,要求每个部分内部的方块之间,可以通过上下左右相互到达,而且每个内部的方块之间互相到达,最多允许拐一次弯,使得两个部分的极差的较大值 最小.(n,m<=2000.)

    分析:"最大值最小"不难想到要二分答案,直接二分两个部分的极差的较大值为(mid),然后(check)时就是构建一个合法的部分,然后判断另一部分是否合法.

    为了保证答案最优,显然矩阵的最大值(maxn)和最小值(minn),要分别在两个部分,至于具体在哪个部分就需要我们枚举了,这里的枚举实际上就是每次翻转矩阵90度,然后去二分答案,连续完成四次,就遍历到了所有的情况.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=2005;
    int n,m,minn=1e9,maxn;
    int a[N][N];
    inline bool check(int mid){
    	int p=m;
    	for(int i=1;i<=n;++i){
    		int t=0; 
    		for(int j=1;j<=p;++j){
    			if(maxn-a[i][j]<=mid)t=max(t,j);//构建一部分
    			else break;
    		}
    		for(int j=t+1;j<=m;++j)
    			if(a[i][j]-minn>mid)return false;//判断另一部分
    		p=t;
    	}
    	return true;
    }
    inline int erfen(){
    	int l=0,r=maxn-minn,ans;
        while(l<=r){
            int mid=(l+r)>>1;
            if(check(mid)){
    			ans=mid;
    			r=mid-1;
    		}
            else l=mid+1;
        }
        return ans;
    }
    int main(){
    	n=read();m=read();
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=m;++j){
    			a[i][j]=read();
    			minn=min(minn,a[i][j]);//最小值
    			maxn=max(maxn,a[i][j]);//最大值
    		}
    	int ans=maxn-minn;//答案上限
    	ans=min(ans,erfen());
    	for(int i=1;i<=n;i++)for(int j=1;j<=m/2;j++)swap(a[i][j],a[i][m-j+1]);//翻转矩阵
    	ans=min(ans,erfen());
    	for(int i=1;i<=n/2;i++)for(int j=1;j<=m;j++)swap(a[i][j],a[n-i+1][j]);
    	ans=min(ans,erfen());
    	for(int i=1;i<=n;i++)for(int j=1;j<=m/2;j++)swap(a[i][j],a[i][m-j+1]);
    	ans=min(ans,erfen());
    	printf("%d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    对于数据的测试
    绕过前端,直接调用后端接口的可能性
    API接口自动化之3 同一个war包中多个接口做自动化测试
    API接口自动化之2 处理http请求的返回体,对返回体做校验
    API接口自动化之1 常见的http请求
    DB中字段为null,为空,为空字符串,为空格要怎么过滤取出有效值
    Linux 常用的压缩命令有 gzip 和 zip
    SQL 常用的命令
    JVM内存管理的机制
    Linux 常见命令
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11558220.html
Copyright © 2011-2022 走看看