矩阵
来源:互联网 发布:unity3d 汽车模型 编辑:程序博客网 时间:2024/06/05 08:30
题目大意
求出一个n*m的矩阵中长至少为x宽至少为y的矩形价值的第K小。
每个元素都是非负整数,一个矩形的价值定义为所有元素和,相同价值的不同矩形在计算答案时算多个。
经典套路
观察一个以(x1,y1)为左上角的矩形。
假如右下角为(x2,y2),这个矩形一定比(x1,y1,x2+1,y2)和(x1,y1,x2,y2+1)都小。
所以先把所有位置为左上角的长为x宽为y的矩形扔进堆里。
每次取出一个矩形,然后将其往下和往右拓展一格的矩形扔进堆里。
我们这样可能拓展到同样的矩形,因此用map判重。
做k次即可。
#include<cstdio>#include<algorithm>#include<map>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;typedef long long ll;typedef pair<int,int> pi;typedef pair<pi,pi> pii;const int maxn=1000+10,maxtot=2000000+10;struct dong{ int x1,y1,x2,y2; ll data; friend bool operator <(dong a,dong b){ return a.data<b.data; }};map<pii,bool> bz;ll sum[maxn][maxn],a[maxn][maxn],cnt;dong heap[maxtot],zlt;int i,j,k,l,t,n,m,x,y,x1,y1,x2,y2,p,tot;ll getsum(int x1,int y1,int x2,int y2){ return sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];}void put(dong x){ heap[++tot]=x; int i=tot; while (i>1&&heap[i]<heap[i/2]){ swap(heap[i],heap[i/2]); i/=2; }}void deletemin(){ heap[1]=heap[tot]; tot--; int i=1,j; while (i*2<=tot){ if (i*2+1>tot||heap[i*2]<heap[i*2+1]) j=i*2;else j=i*2+1; if (heap[j]<heap[i]){ swap(heap[i],heap[j]); i=j; } else break; }}bool pd(){ int i,j,k,l; cnt=0; fo(i,1,n-x+1) fo(j,1,m-y+1) fo(k,x,n-i+1) fo(l,y,m-j+1){ cnt++; if (cnt==p) return 1; } return 0;}bool dp(int x1,int y1,int x2,int y2){ if (bz[make_pair(make_pair(x1,y1),make_pair(x2,y2))]) return 1; bz[make_pair(make_pair(x1,y1),make_pair(x2,y2))]=1;}int main(){ scanf("%d%d%d%d%d",&n,&m,&x,&y,&p); fo(i,1,n) fo(j,1,m) scanf("%lld",&a[i][j]); fo(i,1,n) fo(j,1,m) sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]; if (!pd()){ printf("-1\n"); return 0; } fo(i,1,n-x+1) fo(j,1,m-y+1){ zlt.x1=i; zlt.y1=j; zlt.x2=i+x-1; zlt.y2=j+y-1; bz[make_pair(make_pair(x1,y1),make_pair(x2,y2))]=1; zlt.data=getsum(i,j,i+x-1,j+y-1); put(zlt); } p--; while (p--){ zlt=heap[1]; deletemin(); x1=zlt.x1;y1=zlt.y1; x2=zlt.x2;y2=zlt.y2; if (x2<n&&!dp(x1,y1,x2+1,y2)){ zlt.x2++; zlt.data=getsum(x1,y1,x2+1,y2); put(zlt); zlt.x2--; } if (y2<m&&!dp(x1,y1,x2,y2+1)){ zlt.y2++; zlt.data=getsum(x1,y1,x2,y2+1); put(zlt); } } zlt=heap[1]; printf("%lld\n",zlt.data);}
0 0
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- 矩阵
- C语言字符
- 106. Construct Binary Tree from Inorder and Postorder Traversal
- linux常用命令整理
- android lambda使用:Retrolambda Plugin
- android设计模式初探
- 矩阵
- C语言之static
- Git
- 【蒻爆了的NOIP系列--普及组复赛】(3)NOIP2012普及组复赛题解
- TCP标志位#转载#
- TCP标志位
- 为什么上论坛,会显示我的浏览器和系统版本呢?
- Ztxz16学图论
- Android调试笔记——FATAL EXCEPTION: main...have you declared this activity in your AndroidManifest.xml?