2023 CSP-J/S 复赛(简要思路)
省流:都没 AK,但是思路都没假。(没更新,小声)
upd:J \(400\),S \(385\)。
J
apple
\(O(\log n)\) 模拟,因为 \(n\) 每次乘 \(\frac{2}{3}\)。\(x≡1\mod 3\) 时第 \(x\) 个苹果会被拿走。
road
贪心。每次选价格最少的油加。
uqe
按照题意模拟。\(c=0\) 也许要特判。
bus
我的方法是二分答案然后倒着最短路,\(mn_{i,j}\) 为到了 \(i\) 这个点时间 \(\mod k\) 为 \(j\) 的最短时间。
我的再小图灵上 TLE \(60\),但听说有人过了。
S
lock
可以直接枚举,其实也有一个 \(O(N)\) 的算法。
game
CF 原题。设 \(dp_{i}\) 为结尾为第 \(i\) 个的可以消掉的序列个数。考虑如果有两个相邻的相同的字母,可以把他们消掉。记录一个 map,代表上一个有用的【一个字母】在【那个地方】。两个相邻的相同的字母消掉以后,他们给答案贡献一个 \(1\)(对于一个位置),然后就没用了,可以直接缩掉。
因为我说的很烂,所以相对而讲,代码也许更好懂。
赛时代码
#include <bits/stdc++.h>
using namespace std;
#define de(x) cout<<#x<<"="<<x<<endl
using ll = long long;
const int N = 2e6+6;
ll n,dp[N];
char s[N];
unordered_map<char,int> mp[N];
int main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%lld %s",&n,s+1);
ll ans=0;
for (int i=1; i<=n; i++){
if (mp[i-1].count(s[i])){
int t=mp[i-1][s[i]];
dp[i]+=dp[t-1]+1;
swap(mp[t-1],mp[i]);
}
mp[i][s[i]]=i;
ans+=dp[i];
// cout<<dp[i]<<" ";
}
printf("%lld\n",ans);
return 0;
}
/*
- int/long long?
- memory?
- init for multiple cases?
- modular?
- read the problem statement.
- keep calm.
*/
struct
模拟题,直接模拟即可。我写了 \(4.0\) K/ll
赛时代码
#include <bits/stdc++.h>
using namespace std;
#define de(x) cout<<#x<<"="<<x<<endl
using ll = long long;
const int N = 1e2+2;
struct node {
int k,f;
vector<int> ch;
vector<string> nms;
vector<pair<ll,ll> > mm;
string ty;
string nm;
ll siz,dq;
ll ml,mr;
ll fd(string s){
for (int i=0; i<k; i++){
if (nms[i]==s){
return i;
}
}
return -1;
}
} e[N+5];
struct memory {
ll l,r,ty;
string nm;
} q[N+5];
ll tot,mem,ctmem;
unordered_map<string,int> mp;
unordered_map<string,int> nmp;
void create_struct(){
string nme;
cin>>nme;
mp[nme]=++tot;
cin>>e[tot].k;
e[tot].ch.resize(e[tot].k);
e[tot].nms.resize(e[tot].k);
e[tot].mm.resize(e[tot].k);
ll mx=0,sum=0;
for (int i=0; i<e[tot].k; i++){
string ty;
cin>>ty;
cin>>e[tot].nms[i];
e[tot].ch[i]=mp[ty];
ll dqq=e[e[tot].ch[i]].dq;
ll szz=e[e[tot].ch[i]].siz;
mx=max(mx,dqq);
sum=((sum+dqq-1)/dqq)*dqq;
e[tot].mm[i].first=sum;
e[tot].mm[i].second=sum+szz-1;
// cout<<sum<<"~";
sum=sum+szz;
// cout<<sum-1<<endl;
}
sum=((sum+mx-1)/mx)*mx;
e[tot].siz=sum;
e[tot].dq=mx;
cout<<sum<<" "<<mx<<endl;
}
void create_var(){
string ty,nme;
cin>>ty>>nme;
int typ=mp[ty];
ll cm=mem;
cm=((cm+e[typ].dq-1)/e[typ].dq)*e[typ].dq;
cout<<cm<<endl;
q[++ctmem].l=cm;
q[ctmem].r=cm+e[typ].siz-1;
q[ctmem].nm=nme;
q[ctmem].ty=typ;
nmp[nme]=ctmem;
mem=e[typ].siz+cm;
}
void visit_var(){
string s;
cin>>s;
int i=0;
string bt;
while (i<s.size() && s[i]!='.'){
bt.push_back(s[i++]);
}
ll ct=nmp[bt];
ll lb=q[ct].l,cty=q[ct].ty;
i++;
while (i<s.size()){
string t;
while (i<s.size() && s[i]!='.'){
t.push_back(s[i++]);
}
i++;
ll id=e[cty].fd(t);
lb=lb+e[cty].mm[id].first;
cty=e[cty].ch[id];
}
cout<<lb<<endl;
}
void visit_addr(){
ll ad;
cin>>ad;
string dt="~",res;
int ii;
for (ii=1; ii<=ctmem; ii++){
if (q[ii].l<=ad && ad<=q[ii].r){
dt=q[ii].nm;
break;
}
}
if (dt=="~"){
cout<<"ERR"<<endl;
return;
}
// cout<<"OK"<<endl;
res+=dt;
ll cty=q[ii].ty,lb=q[ii].l,rb=q[ii].r;
// cout<<res<<endl;
while (e[cty].k){
res.push_back('.');
// cout<<res<<endl;
ll id=-1;
for (int i=0; i<e[cty].k; i++){
if (e[cty].mm[i].first+lb<=ad){
id=i;
}
}
if (id<0){
cout<<"ERR"<<endl;
return;
}
if (e[cty].mm[id].second+lb<ad){
cout<<"ERR"<<endl;
return;
}
res+=e[cty].nms[id];
lb=e[cty].mm[id].first+lb;
rb=lb+e[e[cty].ch[id]].siz-1;
cty=e[cty].ch[id];
}
// cout<<"OKK"<<","<<cty<<endl;
if (e[cty].f){
cout<<res<<endl;
}
else{
cout<<"ERR"<<endl;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
//freopen("struct.in","r",stdin);
// freopen("struct.out","w",stdout);
mp["byte"]=1;
mp["short"]=2;
mp["int"]=3;
mp["long"]=4;
e[++tot].f=1;
e[tot].siz=e[tot].dq=1;
e[tot].nm="byte";
e[++tot].f=1;
e[tot].siz=e[tot].dq=2;
e[tot].nm="short";
e[++tot].f=1;
e[tot].siz=e[tot].dq=4;
e[tot].nm="int";
e[++tot].f=1;
e[tot].siz=e[tot].dq=8;
e[tot].nm="long";
int q;
cin>>q;
while (q--){
int op;
cin>>op;
if (op==1){
create_struct();
}
else if (op==2){
create_var();
}
else if (op==3){
visit_var();
}
else{
visit_addr();
}
}
return 0;
}
/*
- int/long long?
- memory?
- init for multiple cases?
- modular?
- read the problem statement.
- keep calm.
*/
tree
思路好像没有假,但是写挂了。
考虑先二分,再 check 答案。先给每个点求出一个值:它最多在多少树之后。然后 dp/贪心 看看有没有不合法即可。