805 字
3 分钟
ABC465
2026-07-20

A. Supermajority#

给定整数 AABB,判断是否有 A>B×23A>B\times \frac{2}{3}.

避免除法,改为判断 A×3>B×2A\times 3>B\times 2.

signed main(){
int a,b;cin>>a>>b;
if(a*3>b*2) cout<<"Yes\n";
else cout<<"No\n";
return 0;
}

B. Parking 2#

停车,从 LL 点到 RR 点整,每小时收费 XX 元,时间段以外收费 YY 元。从 AA 点停到 BB 点,计算收费。

模拟,注意分割点即可。

signed main(){
int x,y,l,r,a,b;cin>>x>>y>>l>>r>>a>>b;
if(a>=r||b<=l){
cout<<(b-a)*y;
}else{
if(a>=l){
if(b<=r){
cout<<(b-a)*x;
}else{
cout<<(r-a)*x+(b-r)*y;
}
}else{
if(b<=r){
cout<<(b-l)*x+(l-a)*y;
}else{
cout<<(b-r+l-a)*y+(r-l)*x;
}
}
}
return 0;
}

C. Reverse Permutation#

给定由 ox 组成的长度为 NN 的字符串 SS 和最初为 (1,2,,N)(1,2,\dots,N) 的整数序列 AA。 对于 k=1,2,,Nk=1,2,\dots,N,当 Sk=S_k= o 时,将 AA 的前 kk 项翻转;当 Sk=S_k= x 时,不做任何操作。输出最后的 AA

注意到,只有 SkS_k 会影响 nn 的位置,当 Sk=S_k= o 时,nn 在输出的最前面,反之则在最后面。 易得,用一个 tag 标记是否翻转,检查每一个 SkS_k 来更改 tag,若翻转,则把 kk 放在输出的最前面,反之放在输出的最后面。用双向队列可以简单地实现。

signed main(){
int n;string s;cin>>n>>s;
deque<int> dq;
int rev=0;
dq.push_back(1);
for(int i=2;i<=n;i++){
if(rev)dq.push_front(i);
else dq.push_back(i);
if(s[i-1]=='o')rev=!rev;
}
if(rev){
reverse(dq.begin(),dq.end());
}
while(dq.size()){
cout<<dq.front()<<' ';
dq.pop_front();
}
return 0;
}

D. X to Y#

给定整数 X,YX,Y 和至少为 22 的整数 KK。 每次操作可以使得满足 xK=y\left\lfloor \frac{x}{K} \right\rfloor=yyK=x\left\lfloor \frac{y}{K} \right\rfloor=xxx 替换为 yy。 问最少多少次可以使得 x=Yx=Y

显然,操作可逆。而将 xx 变大共有 kk 种可能,将 xx 变小则只有一种可能。不妨只变小两者中较大的数,直到相等。由数与数之间的关系做树,易得,这就是最优解。

void solve(){
int x,y,k;cin>>x>>y>>k;
int ans=0;
while(x!=y){
if(x>y)swap(x,y);
y/=k;
ans++;
}
cout<<ans<<endl;
}

E. Digit Circus#

998244353998244353 为模数,问从 1xN1\leq x\leq Nxx 中,有多少满足下面条件中恰好一个:

  • xx33 的倍数。
  • xx 的十进制表示包含 33
  • xx 的十进制表示恰好用了三个不同的数字(没有前导 0)。

显然,数位 DP,不会或者忘记的话看看模板。 太不喜欢数位 DP 了,找了板子来写。。。 DP 共四维,第一维为约束,第二维标记前导 0。 第三维才和本题题意有关,做数字之和模 33 的余数,当余数为 00 时,即满足第一个条件。 最后一维是状态压缩掩码,枚举已有的数字集合,从 009910241024 个状态,要求必须有 33 和另外两个不同的数字。

int dp[2][2][3][1024];
signed main(){
string s;
getline(cin,s);
int n=s.size();
dp[1][1][0][0]=1;
for(int i=0;i<n;i++){
int ndp[2][2][3][1024];
memset(ndp,0,sizeof(ndp));
int upper=s[i]-'0';//当前位最大可选数字
for(int tight=0;tight<2;tight++){
for(int lead=0;lead<2;lead++){
for(int mod=0;mod<3;mod++){
for(int mask=0;mask<1024;mask++){
int val=dp[tight][lead][mod][mask];
if(val==0)continue;
int up=tight?upper:9;//如果当前为约束状态
for(int d=0;d<=up;d++){//枚举当前位的可选数,状态转移
int ntight=(tight&&d==up)?1:0;
int nlead=(lead&&d==0)?1:0;
int nmod=(mod*10+d)%3;
int nmask;
if(nlead) nmask=0;
else if(lead) nmask=1<<d;
else nmask=mask|(1<<d);
ndp[ntight][nlead][nmod][nmask]=(ndp[ntight][nlead][nmod][nmask]+val)%MOD;
}
}
}
}
}
memcpy(dp,ndp,sizeof(dp));
}
int cnt[8]={0};
for(int tight=0;tight<2;tight++){
for(int mod=0;mod<3;mod++){
for(int mask=0;mask<1024;mask++){
int val=dp[tight][0][mod][mask];//不能有前导 0
if(val==0)continue;
int a=(mod==0);//满足条件 1
int b=(mask>>3)&1;//满足条件 2
int c=(__builtin_popcount(mask)==3);//满足条件 3
int idx=(a<<2)|(b<<1)|c;//恰好满足一个条件的只有 4,2,1
cnt[idx]=(cnt[idx]+val)%MOD;
}
}
}
int ans=(cnt[4]+cnt[2]+cnt[1])%MOD;
cout<<ans<<endl;
return 0;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

ABC465
https://leaf146.cn/posts/abc465
作者
LeAf146
发布于
2026-07-20
许可协议
MIT

部分信息可能已经过时