NOI十连测 第四测 T3
思路:
算法一:可以n^2找出每个点的权值,然后n^2做完,预计得分10
算法二:随机找点然后每次找最高。。貌似只有10分?然而考试的时候煞笔了,边界设成inf。。
算法三:随机找几个点,然后随机爬山,听说有50~70
算法四:考虑将列分治,每次分成2部分,找出每部分边界的最大值,判断最大值左边和右边的大小,然后往大的那一边递归,预计得分70
算法五:不仅将列分治,并且将行分治,将一个n*n的矩阵划分,然后递归找,预计得分100
1 #include<bits/stdc++.h> 2 #include"MXPOINT.h" 3 using namespace std; 4 int mp[2010][2010]; 5 int ask(int x,int y){ 6 if (!mp[x][y]) return mp[x][y]; 7 else 8 if (x<1||x>n||y>m||y<1) return mp[x][y]=-1; 9 else return mp[x][y]=ASK(x,y); 10 } 11 bool check(int x,int y){ 12 if (mp[x][y]<=mp[x+1][y]) return 0; 13 if (mp[x][y]<=mp[x][y+1]) return 0; 14 if (mp[x][y]<=mp[x-1][y]) return 0; 15 if (mp[x][y]<=mp[x][y-1]) return 0; 16 return 1; 17 } 18 pair<int,int>find(int lx,int rx,int ly,int ry){ 19 if ((rx-lx)<=3&&(ry-ly)<=3){ 20 for (int i=lx;i<=rx;i++) 21 for (int j=ly;j<=ry;j++) 22 if (check(i,j)) return make_pair(i,j); 23 assert(0); 24 } 25 int mxed=0,idx,idy; 26 for (int i=lx-1;i<=rx+1;i++) 27 for (int j=ly-1;j<=ry+1;j++){ 28 if ((int)(i>=lx&&i<=rx)+(int)(j>=ly&&j<=ry)==2) continue; 29 if (ask(i,j)>mxed){ 30 mxed=ask(i,j); 31 idx=i; 32 idy=j; 33 } 34 } 35 if (rx-lx+1>ry-ly+1){ 36 int mid=(lx+rx)>>1; 37 int mx=0; 38 for (int i=ly;i<=ry;i++) mx=std::max(mx,ask(mid,i)); 39 if (mx<mxed){ 40 if (idx<mid) return find(lx,mid-1,ly,ry); 41 else if (idx==mid) assert(0); 42 else return find(mid+1,rx,ly,ry); 43 } 44 for (int i=ly;i<=ry;i++) 45 if (mx==ask(mid,i)){ 46 int p1=ask(mid-1,i),p2=ask(mid+1,i); 47 if (check(mid,i)) return make_pair(mid,i); 48 else 49 if (p1>mx&&mx>p2) return find(lx,mid-1,ly,ry); 50 else 51 if (p1<mx&&mx<p2) return find(mid+1,rx,ly,ry); 52 else assert(0); 53 } 54 }else{ 55 int mid=(ly+ry)>>1; 56 int mx=0; 57 for (int i=lx;i<=rx;i++) mx=std::max(mx,ask(i,mid)); 58 if (mx<mxed){ 59 if (idy<mid) return find(lx,rx,ly,mid-1); 60 else if (idy==mid) assert(0); 61 else return find(lx,rx,mid+1,ry); 62 } 63 for (int i=lx;i<=rx;i++) 64 if (mx==ask(i,mid)){ 65 int p1=ask(i,mid-1),p2=ask(i,mid+1); 66 if (check(i,mid)) return make_pair(i,mid); 67 else 68 if (p1>mx&&mx>p2) return find(lx,rx,ly,mid-1); 69 else 70 if (p1<mx&&mx<p2) return find(lx,rx,mid+1,ry); 71 else assert(0); 72 } 73 } 74 } 75 pair<int,int> FINDMXPOINT(){ 76 memset(mp,0,sizeof mp); 77 return find(1,2000,1,2000); 78 }