1. 程式人生 > >[HAOI2007]理想的正方形(隨機化,騙分?)

[HAOI2007]理想的正方形(隨機化,騙分?)

col spa 之間 getch div pre 輸入輸出格式 sin ios

題目描述

有一個a*b的整數組成的矩陣,現請你從中找出一個n*n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。

輸入輸出格式

輸入格式:

第一行為3個整數,分別表示a,b,n的值

第二行至第a+1行每行為b個非負整數,表示矩陣中相應位置上的數。每行相鄰兩數之間用一空格分隔。

輸出格式:

僅一個整數,為a*b矩陣中所有“n*n正方形區域中的最大整數和最小整數的差值”的最小值。

思路:

本來想碼二維線段樹,懶了一發,寫了個隨機化,然後過了???

隨機化很簡單,每次隨機一個點作為端點,

n很小,所以每次求差值的時間為最多為n^2=100

加上兩個剪枝,已經跑過的點不再跑

當前位置的差值已經大於已有差值的也跳出

(記得加讀優!!)

代碼:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define rii register int i
#define rij register int j
#define rik register int k
#define inf 1<<30
using namespace std;
int a,b,n,x[1005
][1005],bj[1005][1005]; inline int rd() { char ch = getchar(); int x = 0, f = 1; while(ch < 0 || ch > 9) { if(ch == -) f = -1; ch = getchar(); } while(0 <= ch && ch <= 9) { x = x * 10 + ch - 0; ch = getchar(); } return x * f; }
int main() { a=rd(),b=rd(),n=rd(); for(rii=1;i<=a;i++) { for(rij=1;j<=b;j++) { x[i][j]=rd(); } } long long kkksc03=time(0); srand(kkksc03); int li=a-n+1; int lk=b-n+1; int ans=inf; for(rii=1;i<=350000;i++) { int ltt=rand()%li; ltt++; int kkk=rand()%lk; kkk++; if(bj[ltt][kkk]==1) { continue; } bj[ltt][kkk]=1; int maxn=0; int minx=inf; int pd=0; for(rij=ltt;j<=ltt+n-1;j++) { for(rik=kkk;k<=kkk+n-1;k++) { if(maxn<x[j][k]) { maxn=x[j][k]; } if(minx>x[j][k]) { minx=x[j][k]; } if(maxn-minx>=ans) { pd=1; break; } } if(pd==1) { break; } } if(ans>maxn-minx) { ans=maxn-minx; } } cout<<ans; }

[HAOI2007]理想的正方形(隨機化,騙分?)