其实是复健。上一次碰电脑是期末考试完(7月),上上次是 noip(2023 年 11 月)。
1.P9752 [CSP-S 2023] 密码锁__record
要求:语文没问题,会基础语法,有生活常识。枚状态,判断。几乎没有复杂度要求。
Code
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,ans;
int a[8];
int q[N][8];
void dfs(int t){
if(t==5){
for(int i=1;i<=n;i++){
int f=0;
for(int j=1;j<=5;j++){
if(a[j]!=q[i][j]){
f=1;break;
}
}
if(!f) return;
int pre=-1,num=0;
for(int j=1;j<=5;j++){
if(a[j]!=q[i][j]){
if(num&&(num!=j-1||num==6)) return;
if(pre!=-1&&pre!=(a[j]-q[i][j]+10)%10) return;
pre=(10+a[j]-q[i][j])%10;
if(num) num=6;
else num=j;
}
}
}
ans++;
return;
}
for(int i=0;i<=9;i++){
a[t+1]=i;
dfs(t+1);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=5;j++) scanf("%d",&q[i][j]);
dfs(0);
printf("%d",ans);
return 0;
}
2.P9753 [CSP-S 2023] 消消乐__record
去年糊了一个 35 的暴力,现在也没看懂当时咋写的,有点复杂。
50pts 的 n^2 暴力还是可想的。发现这个消消乐能用栈维护,于是枚举左右段点也就是枚所有子串,用栈处理。栈消空了即说明可以统计答案。
接下来考虑一个性质:如果 s[1,l],s[l+1,r] 都可消,则 s[l,r] 可消;另一个性质:如果用栈维护的序列,在进、出元素后又回到了之前的状态,则说明中间的这段消掉了。
于是把每次操作完的状态哈希后用 map 维护,统计出现的各种状态。这样就把能消的子串都整合起来了。
Code
#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
using namespace std;
const int N=2e6+10;
const ull P=1331;
int n,t;
char a[N],s[N];
ll ans;
ull k,p[N];
map<ull,ll> cnt;
void init(){
p[1]=1;
for(int i=2;i<=N;i++) p[i]=p[i-1]*P;
}
int main(){
scanf("%d",&n);
cin>>a+1;
init();
cnt[k]=1;
for(int i=1;i<=n;i++){
if(t&&s[t]==a[i]) k-=(s[t]-'a'+1)*p[t],t--;
else s[++t]=a[i],k+=(s[t]-'a'+1)*p[t];
ans+=cnt[k];
cnt[k]++;
}
printf("%lld",ans);
return 0;
}
(这个人很愚蠢,看 luogu 第一篇题解没有看懂,只是大受震撼)
3.[]
标签:10.20,const,int,练习,long,10.19,用栈,ull,2023 From: https://www.cnblogs.com/Moyyer-suiy/p/18487411