2022/8/5 启智树考试总结

第一题不是 \(\mathtt{DP}\),可喜可贺。

A.棋盘

(题面待补)

Solution

  • 写了一个复杂度 \(\mathtt{O(2k(n-k)^2)}\) 的暴力,本来估分 \(\mathtt{60pts\sim 80pts}\) 的,居然过了(这玩意儿最坏复杂度不是 2e9 吗)

  • 不过听说有人的 \(\mathtt{O(n^4)}\) 也过了;

  • 大概就是给整张表建一个前缀和矩阵,然后枚举左上角的点坐标,对选定的 \(k\times k\) 的矩阵的每一行和每一列都查一下,如果黑子数不为 \(0\) 且所有黑子都在选定区域内,就 \(\mathtt{++ans}\)(因为没有黑子的行和列最开始就加进答案里了);

AC code
#include<bits/stdc++.h>
using namespace std;

inline int read(){
	int s=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		s=s*10+int(ch-'0');
		ch=getchar();
	}
	return s*f;
}

int n,k;
int h[2005],l[2005];
int mp[2005][2005];
int ans=0;

int get(int a,int b,int c,int d){
	if(a>c || b>d) return 0;
	return mp[c][d]-mp[a-1][d]-mp[c][b-1]+mp[a-1][b-1];
}

int main(){
	n=read(),k=read();
	char opt;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			cin>>opt;
			if(opt=='B')
				++h[i],++l[j],++mp[i][j];
		}
	}
	if(k>=n){
		printf("%d",n<<1);
		return 0;
	}
	for(int i=1;i<=n;++i){
		if(!h[i]) ++ans;
		if(!l[i]) ++ans;
//		h[i]+=h[i-1];
//		l[i]+=l[i-1];
	}
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			mp[i][j]+=mp[i-1][j]+mp[i][j-1]-mp[i-1][j-1];
	int Ans=ans;
	for(int i=1;i+k-1<=n;++i){
		for(int j=1;j+k-1<=n;++j){
			int cnt=ans;
			for(int p=i;p<=i+k-1;++p){
				if(get(p,1,p,j-1)) continue;
				if(j+k<=n && get(p,j+k,p,n)) continue;
				if(mp[p][n]-mp[p-1][n]==0) continue;
				++cnt;
			}
			for(int p=j;p<=j+k-1;++p){
				if(get(1,p,i-1,p)) continue;
				if(i+k<=n && get(i+k,p,n,p)) continue;
				if(mp[n][p]-mp[n][p-1]==0) continue;
				++cnt;
			}
			Ans=max(Ans,cnt);
		}
	}
	printf("%d",Ans);
	return 0;
}
/*
4 2
BWWW
WBBW
WBBW
WWWB

4
*/

B.序列

(题面待补)

Solution

  • 这道题,我败在了第一步——读懂题意;
posted @ 2022-08-05 19:26  Star_LIcsAy  阅读(165)  评论(0)    收藏  举报