题解:P6430 [COCI2008-2009#1] SKAKAVAC
DarkClever · · 题解
一道很好玩的题。
朴素做法是对于每个点,按照
其中
显然,这样子遍历一整个矩阵的复杂度是
初步分析
所以说,我们可以只遍历这
这时,我们考虑到对于每一条,
此时考虑在每一段中不满足
会发现每一段,不满足这个限制的点最多只有
还有一点,注意到
#include <bits/stdc++.h>
using namespace std;
const int N = 1510;
struct node{
short x,y;
int val;
int ans;
}a[N*N];
int n,cnt = 0,r1,c1;
bool cmp(node x,node y){
return x.val < y.val;
}
void ins(node s[],node num){
for(int i=1;i<=4;i++){
if(s[i].ans<num.ans || (s[i].x==0 && s[i].y==0)){
for(int j=4;j>i;j--){
s[j] = s[j-1];
}
s[i] = num;
return;
}
}
return;
}
int query(int x,int y,node l[]){
int maxn = 0;
for(int i=1;i<=4;i++){
if(((abs(l[i].x - x) == 1 && abs(l[i].y - y) > 1) || (abs(l[i].y - y) == 1 && abs(l[i].x - x) > 1)) && l[i].x!=0 && l[i].y!=0){
//cerr<<x<<" "<<y<<" "<<l[i].x<<" "<<l[i].y<<'\n';
maxn = max(maxn,l[i].ans);
}
}
return maxn;
}
node l[N][5];
node r[N][5];
queue<node> q;
signed main() {
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
//cerr.tie(0);
for (int i = 0; i < N; i++) {
for (int j = 0; j < 5; j++) {
l[i][j].ans = 0;
r[i][j].ans = 0;
}
}
cin>>n>>r1>>c1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int x;
cin>>x;
a[++cnt].val = x;
a[cnt].x = i;
a[cnt].y = j;
if(i == r1 && j == c1){
a[cnt].ans = 1;
}
}
}
sort(a+1,a+cnt+1,cmp);
int ans = 1;
int lst = -1;
for(int i=1;i<=cnt;i++){
if(a[i].val!=lst){
for(int j=i-1;j>=0 && a[j].val==lst;j--){
ins(l[a[j].x],a[j]);
ins(r[a[j].y],a[j]);
}
}
lst = a[i].val;
//cerr<<i<<" "<<a[i].x<<" "<<a[i].y<<" "<<a[i].val<<'\n';
int maxn = a[i].ans;
maxn = max(query(a[i].x,a[i].y,l[a[i].x-1]),maxn);
maxn = max(query(a[i].x,a[i].y,l[a[i].x+1]),maxn);
maxn = max(query(a[i].x,a[i].y,r[a[i].y-1]),maxn);
maxn = max(query(a[i].x,a[i].y,r[a[i].y+1]),maxn);
a[i].ans = maxn>0 ? maxn + 1 : 0;
ans = max(ans,a[i].ans);
//cerr<<a[i].ans<<'\n';
}
cout<<ans-1<<'\n';
return 0;
}