2025 ICPC Nanchang Invitational and Jiangxi Provincial Collegiate Programming Contest

A. Nezha Naohai

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
    int a,b,c,d;
    cin>>a>>b>>c>>d;

    cout<<(a+b+c)*d;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int ct=1;
    // cin>>ct;

    while(ct--){
        solve();
    }
}

M. Divide coins

tag:思维题

将前 \(k\) 个放入第一堆,其他的反转并放入第二堆,一定成立,推一下式子就行

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=k;i++){
        cout<<1;
    }
    for(int i=1;i<=n-k;i++){
        cout<<4;
    }
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);  

    int ct=1;
    // cin>>ct;

    while(ct--){
        solve();
    }
}

K. Rotation

tag:思维题

操作一可以转化为,将这个石像逆时针旋转,其他石像不动,参考系也逆时针旋转

一定是使用操作一,将所有石像统一方向后,再操作二

枚举使用操作一把石像统一到 \(0/1/2/3\) 方向即可

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
    int n;
    cin>>n;

    int ans=inf;

    vector<int> a(n+1);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }

    for(int dir=0;dir<4;dir++){
        int now=0;
        int tmp=0;
        for(int i=1;i<=n;i++){
            now-=(a[i]-dir+4)%4;
            tmp+=(a[i]-dir+4)%4;
        }
        now=(now%4+4)%4;
        tmp+=((now-dir)%4+4)%4;
        ans=min(ans,tmp);
    }
    cout<<ans;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int ct=1;
    // cin>>ct;

    while(ct--){
        solve();
    }
}

D. Virtuous Pope

tag:离散化,差分

考虑降维的情况,如果是一维的,可以直接做差分

而三维时,直接分别对 \(x,y,z\) 三个轴上做离散化+差分即可

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
    int n,a,b,c;
    cin>>n>>a>>b>>c;

    vector<pii> x(n+1),y(n+1),z(n+1);

    for(int i=1;i<=n;i++){
        int x1,x2,y1,y2,z1,z2;
        cin>>x1>>y1>>z1>>x2>>y2>>z2;

        x[i]={min(x1,x2),max(x1,x2)};
        y[i]={min(y1,y2),max(y1,y2)};
        z[i]={min(z1,z2),max(z1,z2)};
    }

    int ans=0;

    auto f=[&](vector<pii> t)-> int {
        vector<int> b;
        for(auto [x1,x2]:t){
            b.push_back(x1);
            b.push_back(x2);
        }
        sort(b.begin(),b.end());
        map<int,int> mp;
        int now=1;

        for(auto val:b){
            if(mp[val]) continue;
            mp[val]=now++;
        }

        vector<int> d(n+10);

        for(int i=1;i<=n;i++){
            auto [x1,x2]=t[i];
            d[mp[x1]]++;
            d[mp[x2]+1]--;
        }

        int ans=0;

        for(int i=1;i<=n;i++){
            d[i]+=d[i-1];
            ans=max(ans,d[i]);
        }

        return ans;
    };

    ans=max(ans,f(x));
    ans=max(ans,f(y));
    ans=max(ans,f(z));

    cout<<ans;

}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int ct=1;
    // cin>>ct;

    while(ct--){
        solve();
    }
}

F. Caloric Difference

tag:推公式

推公式发现,\(r\) 越小越好

注意如果用 cout 输出小数,可能输出科学计数法

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
    int n,k;cin>>n>>k;
    double r0,c0,p,l,r;cin>>r0>>c0>>p>>l>>r;
    map<int,int>pos;
    vector<double> num(n+1);
    vector<double> px(n+1);
    for(int i=0;i<k;i++)
    {
        int pi;double vi;cin>>pi>>vi;
        pos[pi]=1;num[pi]=vi;
    }
    px[1]=p;px[0]=1;
    for(int i=2;i<=n;i++)
    px[i]=px[i-1]*p;

    double ans=0;
    for(int i=1;i<=n;i++)
    ans+=px[i]*c0;
    
    ans+=r0;
    pos[0]=1;num[0]=r0;
    for(int i=n;i>=0;i--)
    {
        if(pos[n-i])
        {
            ans-=px[i]*num[n-i];
        }
        else
        ans-=px[i]*l;
    }
    printf("%.8lf",ans);
    cout<<endl;
    }

    
signed main(){
    // ios::sync_with_stdio(0);
    // cin.tie(0);

    int ct;
    cin>>ct;

    while(ct--){
        solve();
    }
}

G. Exploration

tag:最短路,图上 DP

首先一个定理:\((a/b/c/d)=a/(b*c*d)\) 最终取值不会受到下取整影响(除法全部下取整)

所以就可以处理出,\(f[u][i]\) 表示,以 \(u\) 为起点,连续走 \(i\) 步,的边权累乘最大值

对每一个询问,从小到大枚举 \(i\) 就行

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
    int n,m,q;
    cin>>n>>m>>q;

    vector<vector<pii>> g(n+1);
    while(m--){
        int u,v,d;
        cin>>u>>v>>d;
        g[u].push_back({v,d});
    }

    vector f(n+1,vector<int>(33,1));
    for(int i=1;i<=30;i++){
        for(int u=1;u<=n;u++){
            for(auto [v,d]:g[u]){
                f[u][i]=max(f[u][i],d*f[v][i-1]);
            }
        }
    }

    while(q--){
        int p,x;
        cin>>p>>x;

        for(int i=1;i<=30;i++){
            if(f[p][i]>x){
                cout<<i<<endl;
                break;
            }
        }
    }
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int ct=1;
    // cin>>ct;

    while(ct--){
        solve();
    }
}

I. Dating Day

tag: 组合数学,线性 DP

\(f[i]\) 表示,字符串前 \(i\) 个字符,可以变化出的不同个数

需要对每个数,预处理出其最靠左且满足区间和为 \(k\) 的位置

只需要考虑最后一个数的取值即可,不需要考虑容斥

\(i\) 最靠左且满足区间和为 \(k\) 的位置为 \(pos\)

状态转移时,如果当前数不变,则 \(f[i]+=f[i-1]\)

如果 \(s[i]\)\(0\) 变成 \(1\),则 \(f[i]+=C(i-pos,k-1)\) ,意思是一个 \(1\) 放到 \(i\),其他 \(1\) 放到前面

如果 \(s[i]\)\(1\) 变成 \(0\),则 \(f[i]+=C(i-pos,k)\) ,意思是一共 \(k+1\)\(1\) 都要放到前面

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
const int N =  1e5+3;

int fact[N],infact[N];

int qmi(int a,int k,int mod){
    int res=1;
    while(k){
        if(k&1) res=res*a%mod;
        a=a*a%mod;
        k>>=1;
    }
    return res;
}

void init(){
    fact[0]=1;
    for(int i=1;i<N;i++) fact[i]=fact[i-1]*i%mod;
    infact[N-1]=qmi(fact[N-1],mod-2,mod);
    infact[0]=1;
    for(int i=N-2;i>=1;i--) 
        infact[i]=infact[i+1]*(i+1)%mod;
}

int C(int a,int b){
    if(a<b || b<0) return 0;
    return fact[a]*infact[a-b]%mod*infact[b]%mod;
}

void solve(){
    int n,k;
    cin>>n>>k;

    string s;
    cin>>s;
    s=" "+s;

    vector<int> a(n+1),f(n+1),pre(n+1);
    map<int,int> mp;

    for(int i=1;i<=n;i++){
        a[i]=s[i]-'0';
        pre[i]=pre[i-1]+a[i];
        if(mp[pre[i]]==0) mp[pre[i]]=i;
    }

    int p=0;
    for(int i=1;i<=n;i++){
        if(pre[i]<k) continue;
        else if(pre[i]==k){
            f[i]=C(i,k);
            p=i+1;
        }
    }
    if(p==0){
        cout<<0<<endl;
        return;
    }
    for(int i=p;i<=n;i++){
        f[i]=f[i-1];
        int pos=mp[pre[i]-k]+1;
        if(a[i]==0){
            f[i]+=C(i-pos,k-1);
        }
        else{
            f[i]+=C(i-pos,k);
        }

        f[i]%=mod;
    }
    
    cout<<f[n]<<endl;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    init();

    int ct=1;
    cin>>ct;

    while(ct--){
        solve();
    }
}
posted @ 2026-03-27 22:05  LYET  阅读(49)  评论(0)    收藏  举报