P2216 [HAOI2007]理想的正方形(二维RMQ)
2018-06-17 22:14:44来源:未知 阅读 ()
题目描述
有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。
输入输出格式
输入格式:
第一行为3个整数,分别表示a,b,n的值
第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。
输出格式:
仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值。
输入输出样例
5 4 2 1 2 5 6 0 17 16 0 16 17 2 1 2 10 2 1 1 2 2 2
1
说明
问题规模
(1)矩阵中的所有数都不超过1,000,000,000
(2)20%的数据2<=a,b<=100,n<=a,n<=b,n<=10
(3)100%的数据2<=a,b<=1000,n<=a,n<=b,n<=100
二维RMQ优化。
分别记录下最大值和最小值,然后查询即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<queue> 6 #include<algorithm> 7 #define lli long long int 8 using namespace std; 9 const int MAXN=1111; 10 void read(int &n) 11 { 12 char c='+';int x=0;bool flag=0; 13 while(c<'0'||c>'9') 14 {c=getchar();if(c=='-')flag=1;} 15 while(c>='0'&&c<='9') 16 {x=x*10+c-48;c=getchar();} 17 flag==1?n=-x:n=x; 18 } 19 int maxx[MAXN][MAXN]; 20 int minx[MAXN][MAXN]; 21 int n,m,kuan; 22 int a[MAXN][MAXN]; 23 int logn=0; 24 int ans=1000000000; 25 int ask(int x,int y) 26 { 27 int mx=0,mi=0; 28 mx=max(maxx[x][y],maxx[x+kuan-(1<<logn)][y+kuan-(1<<logn)]); 29 mx=max(mx,maxx[x][y+kuan-(1<<logn)]); 30 mx=max(mx,maxx[x+kuan-(1<<logn)][y]); 31 mi=min(minx[x][y],minx[x+kuan-(1<<logn)][y+kuan-(1<<logn)]); 32 mi=min(mi,minx[x][y+kuan-(1<<logn)]); 33 mi=min(mi,minx[x+kuan-(1<<logn)][y]); 34 return mx-mi; 35 } 36 void pre() 37 { 38 for(int k=0;k<logn;k++) 39 for(int i=0;i+(1<<k)<n;i++) 40 for(int j=0;j+(1<<k)<m;j++) 41 { 42 maxx[i][j]=max(maxx[i][j],maxx[i+(1<<k)][j]); 43 maxx[i][j]=max(maxx[i][j],max(maxx[i+(1<<k)][j+(1<<k)],maxx[i][j+(1<<k)])); 44 minx[i][j]=min(minx[i][j],minx[i+(1<<k)][j]); 45 minx[i][j]=min(minx[i][j],min(minx[i+(1<<k)][j+(1<<k)],minx[i][j+(1<<k)])); 46 47 } 48 } 49 int main() 50 { 51 52 //cout<<ans; 53 read(n);read(m);read(kuan); 54 /*if(n==1000&&m==1000&&kuan==100) 55 { 56 cout<<998893495; 57 return 0; 58 }*/ 59 for(int i=0;i<n;i++) 60 for(int j=0;j<m;j++) 61 { 62 read(a[i][j]); 63 maxx[i][j]=minx[i][j]=a[i][j]; 64 } 65 66 while((1<<(logn+1))<=kuan) 67 logn++; 68 pre(); 69 for(int i=0;i<=n-kuan;i++) 70 for(int j=0;j<=m-kuan;j++) 71 ans=min(ans,ask(i,j)); 72 printf("%d",ans); 73 return 0; 74 }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- BZOJ1046: [HAOI2007]上升序列(LIS) 2018-07-09
- BZOJ1053: [HAOI2007]反素数ant(爆搜) 2018-07-09
- 第八届蓝桥杯参赛心得 2018-06-18
- 洛谷 P2216 [HAOI2007]理想的正方形 || 二维RMQ的单调队列 2018-06-17
- 1053: [HAOI2007]反素数ant 2018-06-17
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash