By 虎皮玄椒
805 字
3 分钟
ABC465
A. Supermajority
给定整数 和 ,判断是否有 .
避免除法,改为判断 .
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
停车,从 点到 点整,每小时收费 元,时间段以外收费 元。从 点停到 点,计算收费。
模拟,注意分割点即可。
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
给定由 o 和 x 组成的长度为 的字符串 和最初为 的整数序列 。
对于 ,当 o 时,将 的前 项翻转;当 x 时,不做任何操作。输出最后的 。
注意到,只有 会影响 的位置,当 o 时, 在输出的最前面,反之则在最后面。
易得,用一个 tag 标记是否翻转,检查每一个 来更改 tag,若翻转,则把 放在输出的最前面,反之放在输出的最后面。用双向队列可以简单地实现。
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
给定整数 和至少为 的整数 。 每次操作可以使得满足 或 的 替换为 。 问最少多少次可以使得 。
显然,操作可逆。而将 变大共有 种可能,将 变小则只有一种可能。不妨只变小两者中较大的数,直到相等。由数与数之间的关系做树,易得,这就是最优解。
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
以 为模数,问从 的 中,有多少满足下面条件中恰好一个:
- 是 的倍数。
- 的十进制表示包含 。
- 的十进制表示恰好用了三个不同的数字(没有前导
0)。
显然,数位 DP,不会或者忘记的话看看模板。
太不喜欢数位 DP 了,找了板子来写。。。
DP 共四维,第一维为约束,第二维标记前导 0。
第三维才和本题题意有关,做数字之和模 的余数,当余数为 时,即满足第一个条件。
最后一维是状态压缩掩码,枚举已有的数字集合,从 到 共 个状态,要求必须有 和另外两个不同的数字。
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;}部分信息可能已经过时
