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
- 这道题,我败在了第一步——读懂题意;