TTPC2015 E マス目色ぬり
問題
方針
色が変えられたマスの組合わせを全探索する. 色が変えられたマスからいくつか選び,選んだマスが辺上に来るような長方形をつくる. その幅を±2くらい変えて試す.$O(25 \times 2^K)$.
翌日の D 問題と序盤だけ似てたのでひやっとした.
実装
int N,K;
vvi g;
vi is, js;
int cnt(int i1, int j1, int i2, int j2){
int d = 0;
int di = i2 - i1 + 1;
int dj = j2 - j1 + 1;
if((di*dj)%2 == 1){
if((i1+j1)%2==0) d++; // red;
else d--; // blue
}
rep(ki,K){
int i = is[ki], j = js[ki];
if(i1 <= i && i <= i2 && j1 <= j && j <= j2){
if((i+j)%2==0) d -= 2;
else d += 2;
}
}
return abs(d);
}
int solve(){
int ans = 0;
rep(mask, 1<<K){
if(mask == 0) continue;
int max_i = -1, min_i = N+10, max_j = -1, min_j = N+10;
rep(i,K){
if(mask >> i & 1){
max_i = max<int>(max_i, is[i]);
max_j = max<int>(max_j, js[i]);
min_i = min<int>(min_i, is[i]);
min_j = min<int>(min_j, js[i]);
}
}
rangei(di1,-2,2){
rangei(dj1,-2,2){
rangei(di2,-2,2){
rangei(dj2,-1,2){
int i1 = min_i+di1;
int i2 = max_i+di2;
int j1 = min_j+dj1;
int j2 = max_j+dj2;
if(i1 > i2) continue;
if(j1 > j2) continue;
if(i1 < 0 || j1 < 0) continue;
if(i2 >= N || j2 >= N) continue;
ans = max(ans, abs(cnt(i1,j1,i2,j2)));
}
}
}
}
}
return ans;
}
signed main(){
while(cin >> N >> K){
g.resize(N);
is.clear(), js.clear();
rep(i,N){
g[i].resize(N);
rep(j,N){
g[i][j] = (i+j)%2==0 ? 1 : -1;
}
}
rep(i,K){
int y,x;
cin >> y >> x;
x--, y--;
g[y][x] *= -1;
is.pb(y);
js.pb(x);
}
cout << solve() << endl;
}
}