早上打一半就回家了...

  T1傻逼题不说了...而且我的写法比题解要傻逼很多T T

  T2可以发现,我们强制最大值所在的块是以左上为边界的倒三角,然后旋转4次就可以遍历所有的情况。所以二分极差,把最大值所能扩展到的(mp[i][j]+mid>=mx)最大倒三角求出来,剩下的数减去最小值判断一下是否小于等于极差,如果是的话答案可行。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio> 
#include<algorithm>
#define ll long long 
using namespace std;
const int maxn=2010,inf=1e9;
int mn,mx;
int n[4],m[4],mp[4][maxn][maxn];
bool v[maxn][maxn];
void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
    k*=f;
}
void rotate(int x,int y)
{
    for(int i=1;i<=n[x];i++)
    for(int j=1;j<=m[x];j++)
    mp[y][j][n[x]-i+1]=mp[x][i][j];
    n[y]=m[x];m[y]=n[x];
}
bool check(int x,int mid)
{
    memset(v,0,sizeof(v));
    int now=m[x];
    for(int i=1;i<=n[x];i++)
    for(int j=1;j<=now;j++)
    if(mp[x][i][j]+mid<mx){now=j-1;break;}
    else v[i][j]=1;
    for(int i=n[x];i;i--)
    for(int j=m[x];j;j--)
    if(v[i][j])break;
    else if(mp[x][i][j]-mid>mn)return 0;
    return 1;
}
int main()
{
    read(n[0]);read(m[0]);mn=inf;
    for(int i=1;i<=n[0];i++)for(int j=1;j<=m[0];j++)read(mp[0][i][j]),mx=max(mx,mp[0][i][j]),mn=min(mn,mp[0][i][j]);
    rotate(0,1);rotate(1,2);rotate(2,3);
    int l=0,r=mx-mn;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(0,mid)||check(1,mid)||check(2,mid)||check(3,mid))r=mid;
        else l=mid+1;
    }
    printf("%d\n",l);
    return 0;
}
View Code

相关文章:

  • 2021-08-10
  • 2021-12-06
  • 2022-12-23
  • 2021-10-14
  • 2022-01-23
  • 2021-08-06
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-06-05
  • 2022-12-23
  • 2019-03-03
  • 2022-01-20
  • 2022-12-23
  • 2021-12-25
  • 2021-07-17
相关资源
相似解决方案