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 }

 

posted @ 2016-06-19 20:01  GFY  阅读(306)  评论(0编辑  收藏  举报