A
#include<bits/stdc++.h>
using namespace std;
#define LL long long
string s;
int T,n,ans;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>T;
while(T--) {
cin>>n;
cin>>s;
ans=0;
for(int i=0;i<n;i++) {
if(s[i] == '@') {ans++; continue;}
if(i == n-1) break;
if(s[i] == '.') continue;
if(s[i+1] == '*') break;
}
cout<<ans<<"\n";
}
return 0;
}
B
#include<bits/stdc++.h>
using namespace std;
#define LL long long
int T,n,a[110],ans;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>T;
while(T--) {
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
ans = a[1];
for(int i=2;i<=n;i++) {
int x = ans % a[i];
ans+=(a[i] - x);
}
cout<<ans<<"\n";
}
return 0;
}
C
先求出终止状态,然后倒推模拟。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 2e5+10;
int T,n,m,a[N],ans[N];
string s;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>T;
while(T--) {
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],a[i]%=m;;
cin>>s;
int p=0,q=n+1;
for(int i=0;i<n;i++) {
if(s[i] == 'L') p++;
else q--;
}
ans[n+1] = 1;
for(int i=n-1;i>=0;i--) {
if(s[i] == 'L') ans[i+1] = ans[i+2]*a[p]%m,p--;
else ans[i+1] = ans[i+2]*a[q]%m,q++;
}
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
cout<<"\n";
}
return 0;
}
D
模拟,优先消耗非王牌的牌。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
int T,n;
int card[5][10],cnt[4];
char flag;
char f(int x) {
if(x == 0) return 'C';
if(x == 1) return 'D';
if(x == 2) return 'H';
if(x == 3) return 'S';
}
int g(char x) {
if(x == 'C') return 0;
if(x == 'D') return 1;
if(x == 'H') return 2;
if(x == 'S') return 3;
}
char ans[200][5];
void init() {
memset(card,0,sizeof(card));
memset(cnt,0,sizeof(cnt));
memset(ans,0,sizeof(ans));
}
int tot;
void solve() {
int sum = 0;
tot = 0;
for(int i=0;i<4;i++) sort(card[i]+1,card[i]+cnt[i]+1);
for(int i=0;i<4;i++) {
if(i == g(flag)) continue;
while(cnt[i] >= 2) {
char num1 = '0' + card[i][cnt[i]],num2 = '0' + card[i][cnt[i]-1];
cnt[i]-=2;
ans[++tot][0] = f(i); ans[tot][1]=num2;
ans[++tot][0] = f(i); ans[tot][1]=num1;
}
sum += cnt[i];
}
if(sum > cnt[g(flag)]) {
cout<<"IMPOSSIBLE\n";
return;
}
int js=0;
for(int i=0;i<4;i++) {
if(i == g(flag)) continue;
if(cnt[i]) {
char num1 = '0' + card[i][cnt[i]],num2 = '0' + card[g(flag)][++js];
ans[++tot][0] = f(i); ans[tot][1]=num1;
ans[++tot][0] = flag; ans[tot][1]=num2;
}
}
while(js < cnt[g(flag)]) {
char num1 = '0' + card[g(flag)][js+1],num2 = '0' + card[g(flag)][js+2];
ans[++tot][0] = flag; ans[tot][1]=num1;
ans[++tot][0] = flag; ans[tot][1]=num2;
js+=2;
}
for(int i=1;i<=tot;i+=2) {
cout<<ans[i][1]<<ans[i][0]<<" "<<ans[i+1][1]<<ans[i+1][0]<<"\n";
}
return;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>T;
while(T--) {
cin>>n;
cin>>flag;
init();
string t;
for(int i=1,id;i<=2*n;i++) {
cin>>t;
id=g(t[1]);
card[id][++cnt[id]] = t[0]-'0';
}
solve();
}
return 0;
}
E
设 $dp_i$ 为第 $i$ 位对最终答案的贡献,因为上一位每变化一次第 $i$ 位会变化 $10$ 次,所以有 $dp_i = 10dp_{i-1}+a_i$,把 $dp_{i-1}$ 依次消掉,有 $dp_i = \sum_{k=1}^{i} a_k 10^{i-k}$,整理一下后,我们得到答案的第 $i$ 位为 $ans_i = \sum_{k=1}^{n-i} a_k$ ,之后按位处理答案每一位的进位即可。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 4e5+1000;
int T,n,a[N];
string s;
int ans[N];
void solve() {
for(int i=1,sum=0;i<=n;i++) {
sum+=a[i];
ans[n-i+1]=sum;
}
int p=1;
while(ans[p] || p <= n) {
ans[p+1]+=ans[p]/10;
ans[p]%=10;
p++;
}
while(!ans[p]) p--;
for(int i=p;i>=1;i--) {
cout<<ans[i]; ans[i]=0;
}
cout<<"\n";
return;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>T;
while(T--) {
cin>>n;
cin>>s;
for(int i=0;i<n;i++) a[i+1] = s[i] - '0';
solve();
}
return 0;
}
F
设 $b_i$ 为能覆盖第 $i$ 个位置的线段能延伸到的最右端,$num_i$ 为 $i$ 被覆盖的次数,$dp_i$ 表示从 $i$ 开始向右取数能达到的最大答案,有转移方程 $dp_i = max \{ dp_j \} + num_i, j > b_i$,预处理完 $num_i$,$b_i$ 后直接转移即可,用优先队列优化决策后复杂度为 $O(nlogn)$。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e6+10;
const int M = 2e5+10;
int T,n,m,b[N],num[N],dp[N];
struct cat {
int l,r;
} a[M];
int lx,rx;
bool cmp(cat x,cat y) {
if(x. r == y.r) return x.l > y.l;
return x.r < y.r;
}
void init() {
sort(a+1,a+m+1,cmp);
for(int i=1;i<=n;i++) num[i]+=num[i-1];
a[m+1].r=0;
for(int i=m,R=rx;i>=1;i--) {
if(a[i].r != a[i+1].r) {
for(int j=a[i].l;j<=R;j++) {
b[j] = a[i].r;
}
R=min(R,a[i].l-1);
}
}
return;
}
void solve() {
int ans = 0;
priority_queue<int> q;
q.push(0);
for(int i=n,j=n;i>=1;i--) {
while(j > max(i,b[i])) q.push(dp[j]),j--;
dp[i]=q.top()+num[i];
ans=max(ans,dp[i]);
}
cout<<ans<<"\n";
return;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>T;
while(T--) {
cin>>n>>m;
for(int i=0;i<=n+1;i++) {dp[i]=0; b[i]=0; num[i]=0;}
lx=1e9; rx=0;
for(int i=1;i<=m;i++) {
cin>>a[i].l>>a[i].r;
num[a[i].l]++; num[a[i].r+1]--;
lx=min(lx,a[i].l); rx=max(rx,a[i].r);
}
init();
solve();
}
return 0;
}
G
转换完后是个不定方程,用Exgcd求解即可。代码待补。