The 2023 ICPC Xi'an Invitational Programming Contest / 2023 ICPC 全国邀请赛 西安

G. Permutation

直接输出 1 到 n

J. Target

一开始想了半天可不可以找一个中间值,使得 \(a,b\) 都一定能变成中间值

后来发现,可以先把 \(a\) 变成 \(0\),之后 \(a\) 的每次操作实际就是,在 \(a\) 的二进制位表示下,给小数的每一位赋值 \(1\)\(0\)

二进制逼近 \(b\) 即可

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
using ll=long long; 
using pii=pair<int,int>;
const ll inf = 1e18;
const int mod = 1e9+7;

const double eps1=1e-6;
const double eps=1e-4;

void solve(){
    double a,b,s=0.5;

    cin>>a>>b;
    int cnt=0;

    while(a>=eps1 && cnt<50){
        cnt++;
        a=a*s;
        cout<<1;
    }

    vector<int> ans;

    while(b>=eps1){
        if(b>=s){
            ans.push_back(2);
            b-=s;
        }
        else ans.push_back(1);
        s=0.5*s;
    }

    for(int i=ans.size()-1;i>=0;i--){
        cout<<ans[i];
    }
    
}

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

    int ct=1;
    // cin>>ct;
    while(ct--) solve();

    return 0;
}

A. Alice and Bob

VP 时还没看题队友就把思路出完了,给我讲了个大致的排列方法,我只需要推一下组合数学式子+写代码就 A 了。好爽

\(Alice\) 先手,对于一个固定的 \(p[1]\),如果 \(p[1,p1]\) 中,的最小值小于 \(p[1]\),则把最小值放到最前面,先手一定赢

如果最小值大于 \(p[1]\),则先手一定输

证明是容易手搓出来的

然后就是组合数学,可以直接算输的情况,对于一个固定的 \(p[1]=i\),先手输的情况数为:\(C(n-i,i-1)*(i-1)!*(n-i)!\)

\(C(n-i,i-1)\) 表示从 \(n-i\) 个比 \(i\) 的数中,选 \(i-1\) 个的组合数,后面两个阶乘是这两部分的排列

枚举 \(i\) 累加答案即可

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

const int N=1e7;
vector<int> fact(N+1),infact(N+1);

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

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

    for(int i=N-1;i>=1;i--){
        infact[i]=infact[i+1]*(i+1)%mod;
    }
}

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

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

    int ans=0;
    for(int i=1;i<=n;i++){
        ans+=C(n-i,i-1)*fact[i-1]%mod*fact[n-i]%mod;
        ans%=mod;
    }

    cout<<ans;
}

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

    init();

    int ct=1;
    // cin>>ct;
    while(ct--) solve();

    return 0;
}

H. Spin the Wheel

VP 的时候还是不够冷静/理性,没有去一点一点考虑所有情况,导致没找出 111111 和数组中没 0 时的情况

首先,可以观察到,在取模的意义下,如果相邻两个数的差存在数值不同的情况,则一定是 -1

因为,每次相加,都会让差值固定 +1

设差值为 \(d\)\(0<=d<n\)

如果 \(d=0\):

  1. 如果数组是全零,则答案为 \(0\)
  2. 否则答案为 \(n+1\),手搓一下能找出来。(最小是 \(n\) 次,因为要让公差为 \(n\)

如果 \(d!=0\):

  1. 如果 \(a[1]\) 是零,则直接累加 \(d\)\(0,1,2,3,4,...,n-1\) 即可,答案为 \(d\)
  2. 否则答案为 \(d+1\),可以先累加 \(d\) 次,然后转一下
posted @ 2026-03-12 19:13  LYET  阅读(8)  评论(0)    收藏  举报