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\):
- 如果数组是全零,则答案为 \(0\)
- 否则答案为 \(n+1\),手搓一下能找出来。(最小是 \(n\) 次,因为要让公差为 \(n\)
如果 \(d!=0\):
- 如果 \(a[1]\) 是零,则直接累加 \(d\) 次 \(0,1,2,3,4,...,n-1\) 即可,答案为 \(d\)
- 否则答案为 \(d+1\),可以先累加 \(d\) 次,然后转一下

浙公网安备 33010602011771号