[CSP 2025]游記
CSP-J
$T1$
循環結構 $+$ 字符串,橙題,不說了肯定做出來了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 2000005
int top,a[N];
string s;
signed main(){
cin>>s,s=" "+s;
for(int i=1;i<s.length();i++) if(s[i]>='0'&&s[i]<='9') a[++top]=s[i]-'0';
sort(a+1,a+top+1);
for(int i=top;i;i--) cout<<a[i];
return 0;
}
$T2$
循環結構 $+$ 小學數學,橙題,不說了肯定做出來了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 2000005
int n,m,x,y,cnt,a[N];
signed main(){
cin>>n>>m;
for(int i=1;i<=n*m;i++){cin>>a[i];if(a[i]>=a[1]) cnt++;}
x=cnt/n+(cnt%n!=0);
if(x%2==1) y=cnt-n*(x-1);
else y=n-(cnt-n*(x-1))+1;
cout<<x<<" "<<y<<endl;
return 0;
}
$T3$
貪心 $+$ 紅黑樹($map$),黃題,不說了肯定做出來了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 2000005
int n,k,a[N],pre[N],cnt;
map<int,int>mp;
signed main(){
cin>>n>>k;
mp[0]=-1;
for(int i=1,r=-1;i<=n;i++){
cin>>a[i];
pre[i]=pre[i-1]^a[i];
if(mp[pre[i]^k]!=0&&mp[pre[i]^k]>=r) r=i,cnt++;
mp[pre[i]]=i;
}
cout<<cnt<<endl;
return 0;
}
$T4$
普通背包 $+$ 出題人好心的幫忙解決了的數學部分,綠題,不說了肯定做出來了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 5005
#define mx 5000
#define md 998244353
int n,a[N],dp[N],ans;
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
dp[0]=1;
for(int i=1;i<=n;i++){
for(int j=a[i]+1;j<=mx+1;j++) ans=(ans+dp[j])%md;
for(int j=mx+1;j>=mx+1-a[i];j--) dp[mx+1]=(dp[j]+dp[mx+1])%md;
for(int j=mx;j>=a[i];j--) dp[j]=(dp[j]+dp[j-a[i]])%md;
}
cout<<ans<<endl;
return 0;
}
$對拍$
- $T1$ 打了暴搜。
- $T2$ 打了模擬。
- $T3$ 打了暴搜。
- $T4$ 打了狀壓。
最后四個對拍一起跑了 $1$ 個小時。
遺憾監考老師強調不能玩 $dino$。
CSP-S
$T1$
- 先不管集合的數要 $\le \frac{n}{2}$ 的條件,貪心直接放。
- 如果數最多的集合的數 $> \frac{n}{2}$,取出放入其他集合后對答案影響最小的幾個數,放入其他集合。可以證明,此時其他集合數的個數都會 $\le \frac{n}{2}$。
- 此時答案最優。
挺簡單,不到半小時就調完了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 200005
#define mx 5000
#define md 998244353
int t,n,a[N],ans;
struct PT{int p[N],top;}q[4];
bool cmp(PT a,PT b){return a.top>b.top;}
signed main(){
cin>>t;
while(t--){
cin>>n;
ans=q[1].top=q[2].top=q[3].top=0;
for(int i=1,a,b,c;i<=n;i++){
cin>>a>>b>>c;
if(a>=b&&a>=c) q[1].p[++q[1].top]=min(a-b,a-c),ans+=a;
else if(b>=c&&b>=a) q[2].p[++q[2].top]=min(b-a,b-c),ans+=b;
else if(c>=b&&c>=a) q[3].p[++q[3].top]=min(c-b,c-a),ans+=c;
}
sort(q+1,q+3+1,cmp);
for(int i=1;i<=q[1].top;i++) a[i]=q[1].p[i];
sort(a+1,a+q[1].top+1);
for(int i=1;i<=q[1].top-n/2;i++) ans-=a[i];
cout<<ans<<endl;
}
return 0;
}
$T2$
- 先求出 $n$ 個點 $m$ 條邊的最小生成樹。
- 狀壓 $k$ 個鄉鎮,與原先最小生成樹的邊一起再求最小生成樹,更新答案。
時間復雜度 $O(m\log_{2}{m}+2^knk\log_{2}{k})$?不太對勁。造了個大數據,跑了 $3$ 秒,又調了一個小時,還是 $3$ 秒,最后相信評測機,不調了。
賽后在 $luogu$ 跑得飛快。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 2000005
int n,m,k,f[N],top,c[N],ans;
struct EDGE{int u,v,fr;}edge[N],p[15][20005];
struct VL{int fr,pt;}pp[N];
bool cmp(EDGE a,EDGE b){return a.fr<b.fr;}
bool cmpp(VL a,VL b){return a.fr<b.fr;}
int find(int w){return w==f[w]?w:f[w]=find(f[w]);}
priority_queue<pair<int,pair<int,int> >,vector<pair<int,pair<int,int> > >,greater<pair<int,pair<int,int> > > >q;
signed main(){
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=1;i<=m;i++) scanf("%lld%lld%lld",&edge[i].u,&edge[i].v,&edge[i].fr);
sort(edge+1,edge+m+1,cmp);
for(int i=1;i<=m;i++) f[i]=i;
for(int i=1;i<=m;i++){
if(find(edge[i].u)==find(edge[i].v))continue;
p[0][++top]=edge[i],ans+=edge[i].fr;
f[find(edge[i].u)]=find(edge[i].v),find(edge[i].u);
}
for(int i=1;i<=k;i++){
scanf("%lld",&c[i]);
for(int j=1;j<=n;j++) scanf("%lld",&pp[j].fr),pp[j].pt=j;
sort(pp+1,pp+n+1,cmpp);
for(int j=1;j<=n;j++) p[i][j].u=n+i,p[i][j].v=pp[j].pt,p[i][j].fr=pp[j].fr;
}
for(int i=1;i<(1<<k);i++){
while(!q.empty())q.pop();
int anss=0,up=n-1,top=0;
q.push({p[0][1].fr,{0,1}});
for(int j=1;j<=k;j++) if((i>>(j-1))&1) q.push({p[j][1].fr,{j,1}}),up++,anss+=c[j];
for(int i=1;i<=n+k;i++) f[i]=i;
while(top!=up){
int x=q.top().second.first,y=q.top().second.second;
q.pop();
if(p[x][y+1].u!=0) q.push({p[x][y+1].fr,{x,y+1}});
if(find(p[x][y].u)==find(p[x][y].v))continue;
++top;f[find(p[x][y].u)]=find(p[x][y].v),find(p[x][y].u);anss+=p[x][y].fr;
}
ans=min(anss,ans);
}
printf("%lld\n",ans);
return 0;
}
$T3$
寫了個接近 $100$ 行的 $trie+hash$, 在比賽還剩 $5$ 分鐘才能運行,最后小樣例過了,大樣例沒過,絕對 $TLE$。
無代碼。
$T4$
只看了題。
預估
| $T1$ | $T2$ | $T3$ | $T4$ | $sum$ | |
|---|---|---|---|---|---|
| J | 100 | 100 | 100 | 100 | $\le 400$ |
| S | 100 | 100 | 0 | 0 | 200 |
希望吧。
浙公網安備 33010602011771號