round 624
A水题
B
先从小到大排序,然后判断有多少是连着的可排序的,如果发现当前不连着,就把刚刚记录下来的位置进行局部排序,然后更新位置,所以我们只要看是否有间断,间断就局部排序一次。
最后判断所有数是不是从小到大就行了
#include <bits/stdc++.h> using namespace std; bool tt; int t,a[105],b[105],n,m,i,num; int main() { cin>>t; while (t--) { cin>>n>>m; for (i=1;i<=n;i++) { scanf("%d",&a[i]); } for (i=1;i<=m;i++) { scanf("%d",&b[i]); } sort(b+1,b+1+m); num=b[1]; b[m+1]=0; for (i=1;i<=m;i++) { if (b[i]+1!=b[i+1]) { sort(a+num,a+b[i]+2); num=b[i+1]; } } tt=true; for (i=1;i<=n-1;i++) if (a[i]>a[i+1]) { tt=false; break; } if (tt) cout<<"YES"<<endl; else cout<<"NO"<<endl; } }
C
先从小到大排序,然后用前缀和思想就行了。注意如果有相等的情况,就把相等的给忽略掉。
#include <bits/stdc++.h> #define maxn 200005 using namespace std; string ss,s,num[maxn]; int t,i,n,m,a[maxn],j; long long k[maxn]; int main() { cin>>t; while (t--) { scanf("%d%d",&n,&m); getchar(); getline(cin,s); for (i=1;i<=m;i++) scanf("%d",&a[i]); sort(a+1,a+1+m); memset(k,0,sizeof(k)); for (i=0;i<n;i++) k[s[i]-'a'+1]++; int num=0; for (i=1;i<=m;i++) { if (a[i]==a[i-1]) continue; while (num<a[i]) { k[s[num]-'a'+1]+=m-i+1; num++; } } for (i=1;i<=26;i++) printf("%lld ",k[i]); cout<<endl; } }
赛后补题
D没写,但是看了别人的题解,发现就是枚举A’,然后以一倍的A‘,两倍的A’,三倍的A‘......来枚举B’。A‘ B’都枚举出来后,就可以算C要减或加多少才能整除B‘,然后就选择操作最少次的那个就代表C‘
最后输出答案就完事了
F题在2020 2月25日发的另一个博客。