1 条题解
-
0
自动搬运
来自洛谷,原作者为

Anoxiacxy
**搬运于
2025-08-24 21:54:17,当前版本为作者最后更新于2017-10-21 16:17:39,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
对于这种最优化问题,我们可以二分答案啊,显然,最大值和最小值一定不被划分到一个区域里,那么我们假定最大值在矩形的上三角里,对于那些大于最大值减去我们二分的答案的数,都是符合要求的,然后判断不在当前区域的数,是不是都小于最小值加上我们二分的答案,由于最大值,最小值的位置不确定,所以我们可以把矩阵旋转四次,分别判断即可,只要有一种满足条件即可
以下为英语短文填空裸题,后附参考答案
#include <cstdio> #include <cstring> #include <iostream> #define inf int(2e9) #define nl NULL using namespace std; int ___,____;int ______________=0,_____________=inf; int _________________[4][2017][2017],_______________=3; bool __________________[2017][2017]; void ________(int ___________________,int ____________________){ for(int _=1;_<=___;_++) for(int __=1;__<=____;__++) _________________[____________________][__][___-_ + 1]=_________________[___________________][_][__]; swap(____ ,___); } bool _________(int ________________){ int ____________=____; memset(__________________,0,sizeof(__________________)); for(int _=1;_<=___;_++) for(int __=1;__<=____________;__++) if(_________________[_______________][_][__]+________________<______________){ ____________=__-1;break; }else __________________[_][__] = true; for(int _=___;_; _--) for(int __=____; __; __--) if(__________________[_][__])break; else if(_________________[_______________][_][__]-________________>_____________)return false; return true; } void ___________(){swap(___,____);_______________=(_______________+1)%4;} bool __________(int ________________){ if(_________(________________)) return true; ___________(); if(_________(________________)) return true; ___________(); if(_________(________________)) return true; ___________(); if(_________(________________)) return true; ___________(); return false; } int main(){ scanf("%d%d",&___,&____); for(int _=1;_<=___;_++)for(int __=1;__<=____;__++){ scanf("%d",&_________________[0][_][__]); ______________=max(______________,_________________[0][_][__]); _____________=min(_____________,_________________[0][_][__]); } ________(0,1);________(1,2);________(2,3); int _____=0,______=______________-_____________; while(_____<______){ int _______=_____+______ >> 1; if(__________(_______))______=_______; else _____=_______+1; } printf("%d",_____); }参考答案
#include <cstdio> #include <cstring> #include <iostream> #define inf int(2e9) #define nl NULL using namespace std; int n,m;int maxv = 0, minv = inf; int a[4][2017][2017], coc = 3; bool f[2017][2017]; void rotate(int s,int t){ for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) a[t][j][n - i + 1] = a[s][i][j]; swap(m ,n); } bool deal(int ans){ int p = m; memset(f, 0, sizeof(f)); for(int i = 1; i<= n; i++) for(int j = 1; j <= p; j++) if(a[coc][i][j] + ans < maxv){ p = j - 1; break; }else f[i][j] = true; for(int i = n; i; i--) for(int j = m; j; j--) if(f[i][j]) break; else if(a[coc][i][j] - ans > minv) return false; return true; } void nxt() {swap(n, m); coc = (coc + 1) % 4; } bool check(int ans){ if(deal(ans)) return true;nxt(); if(deal(ans)) return true;nxt(); if(deal(ans)) return true;nxt(); if(deal(ans)) return true;nxt(); return false; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){ scanf("%d",&a[0][i][j]); maxv = max(maxv, a[0][i][j]); minv = min(minv, a[0][i][j]); } rotate(0, 1); rotate(1, 2); rotate(2, 3); int l = 0, r = maxv - minv; while(l < r){ int mid = l + r >> 1; if(check(mid)) r = mid; else l = mid + 1; } printf("%d", l); }
- 1
信息
- ID
- 2886
- 时间
- 1000~3000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者