codeforces1200D White Lines

传送门

题意:给你n k,矩形面积n * n,橡皮尺寸k * k。橡皮只能使用一次,问你使用过后white line(白色横行+白色竖行)最多有多少条?

思路:

各种前缀和qaq

tu——原本的图;G——01图black映射成1,white映射成0;

GR,GC——对图G分别就行 列求前缀和

chan_R,chan_C,以当前i,j坐标为eraser左边界(上边界)是否会对这一列(行)有贡献(增添一个white line)

add_R,对chan_C求前缀和表示add_R[i][j]对于row-i,从第1列到第j列有多少能变成column of white

add_C,对chan_R求前缀和表示add_C[i][j]对于column-j,从第1行到第i列有多少能变成row of white

求MaxAns是卡住一个k * k求max + 原本就存在的white lines

AC代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>

using namespace std;

int n,k,ans,ANS;
char tu[2005][2005];
int G[2005][2005];
int GR[2005][2005],GC[2005][2005];
bool chan_R[2005][2005],chan_C[2005][2005];
int add_R[2005][2005],add_C[2005][2005];

int main()
{
	scanf("%d %d",&n,&k);
	ans = 0;
	for(int i = 1;i <= n; i++){
		for(int j = 1;j <= n; j++){
			scanf(" %c",&tu[i][j]);
			if(tu[i][j] == 'B') G[i][j] = 1;
		}
	}
	//R 行     C 列
	for(int i = 1;i <= n; i++){
		for(int j = 1;j <= n; j++){
			GR[i][j] = GR[i][j - 1] + G[i][j]; 
			GC[i][j] = GC[i - 1][j] + G[i][j];
		}
	}
	for(int i = 1;i <= n; i++){
		if(!GR[i][n]) ans++;
		if(!GC[n][i]) ans++;
	}
	//已经拥有的 white lines

	for(int i = 1;i <= n; i++){
		for(int j = 1;j + k - 1 <= n; j++){
			if(GR[i][n]){
				chan_R[i][j] = (GR[i][j + k - 1] - GR[i][j - 1] == GR[i][n]);
			}
			if(GC[n][i]){
				chan_C[j][i] = (GC[j + k - 1][i] - GC[j - 1][i] == GC[n][i]);
			}
		}
	}
	//eraser 在(i,j)作为左上角时 if(this row turn to white)
	//eraser 在(j,i)作为左上角时 if(this column turn to white)
/*
cout << "-------------------------"<<endl;
for(int i = 1;i <= n ;i++){
	for(int j = 1;j <= n; j++){
		cout << chan_R[i][j] << " ";
	}
	cout << endl;
}
cout << "--------------------------"<<endl;
for(int i = 1;i <= n ;i++){
	for(int j = 1;j <= n; j++){
		cout << chan_C[i][j] << " ";
	}
	cout << endl;
}
*/

	for(int i = 1;i <= n; i++){
		for(int j = 1;j <= n; j++){
			add_R[i][j] = add_R[i][j - 1] + chan_C[i][j];
			add_C[i][j] = add_C[i - 1][j] + chan_R[i][j];
		}
	}
/*
cout << "-------------------------"<<endl;
for(int i = 1;i <= n ;i++){
	for(int j = 1;j <= n; j++){
		cout << add_R[i][j] << " ";
	}
	cout << endl;
}
cout << "--------------------------"<<endl;
for(int i = 1;i <= n ;i++){
	for(int j = 1;j <= n; j++){
		cout << add_C[i][j] << " ";
	}
	cout << endl;
}
cout <<"-----------------------------------------------\n";
*/
	ANS = 0;
	for(int i = 1;i + k - 1 <= n; i++){
		for(int j = 1;j + k - 1 <= n; j++){
			int cur = add_R[i][j + k - 1] - add_R[i][j - 1] + add_C[i + k - 1][j] - add_C[i - 1][j];
			ANS = max(ANS,cur);
		}
	}
	printf("%d\n",ANS + ans);
}
发布了31 篇原创文章 · 获赞 5 · 访问量 1379

猜你喜欢

转载自blog.csdn.net/qq_43685900/article/details/99447033