B - WeirdSort(思维模拟)
题意: 给出一个长度为n的数组a[],还有一个长度为m的数组p[],pi表示能将数组a位置为pi和pi+1互换,问能否将数组a变为一个不下降的数组。
题解: 用结构体记录下数的值和下标,按值sort一遍,然后遍历,如果有排序后下标和之前的下标不同的,两个下标之间是否都能进行操作,如果不行则不能达到目的输出NO , 如果当前的值和两下标之间的值有相同的时候则跳出两下标检查的循环。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
const int N=110 ;
struct node{
int id,val ;
}a[N] ;
int p[N] ;
bool cmp(node x,node y){
if(x.val==y.val) return x.id<y.id ;
return x.val < y.val ;
}
int main(){
int t; scanf("%d",&t) ;
while(t--){
memset(p,0,sizeof(p)) ;
int n,m,x ; scanf("%d%d",&n,&m) ;
for(int i=1 ; i<=n ; ++i) scanf("%d",&a[i].val),a[i].id=i ;
for(int i=0 ; i<m ; ++i) scanf("%d",&x),p[x]=1 ;
sort(a+1,a+1+n,cmp) ;
bool flag = true ;
for(int i=1 ; i<=n&&flag ; ++i){
if(a[i].id > i){
for(int j=i+1 ; j<a[i].id ; ++j){
if(a[j].val==a[i].val) break ;
if(p[j]==0){flag=false ; break ; }
}
}
else{
for(int j=a[i].id ; j<i ; ++j){
if(a[j].val==a[i].val) break ;
if(p[j]==0){flag=false;break ;}
}
}
}
if(flag) printf("YES\n") ;
else printf("NO\n") ;
}
return 0 ;
}
C - Perform the Combo(后缀和)
题意: 给出一个长度为n的字符串,还有m个操作,x表示从1到x的字符次数加一,最后整个字符串操作一次,然后打印出a~z每次字符被操作的次数。
题解: 每次输入x,在x的位置加一,然后从后往前遍历一遍求后缀和,然后每个字符串的位置上的字符加上后缀和数组的次数。
#include <iostream>
#include <cstring>
#include <vector>
using namespace std ;
const int N=2e5+5 ;
int p[N] , a[26] ;
int main(){
int t ; cin>>t ;
while(t--){
memset(p,0,sizeof(p)) ;
memset(a,0,sizeof(a)) ;
int n,m; cin>>n>>m ;
string s ; cin>>s ;
for(int i=0 ; i<m ; ++i){
int x ; cin>>x ;
++ p[x] ; //操作位置加一
}
++p[n] ; //整个字符串的操作
for(int i=n-1 ; i>0 ; --i) p[i]+=p[i+1] ; //求后缀和
for(int i=1 ; i<=n ; ++i){
a[s[i-1]-'a']+=p[i] ; //求每个位置上的字符位置
}
for(int i=0 ; i<25 ; ++i)
printf("%d ",a[i]) ;
printf ("%d\n",a[25]) ;
}
return 0 ;
}
D - Three Integers(暴力枚举)
题意: 给出a,b,c,每个正数都可以进行+1或者-1的操作,使得a<=b<=c
b可以被a整除,c可以被b整除,问操作数最少为多少并打印出操作后的abc
题解: a为b的因子,c为b的倍数,枚举记录最小值即可
#include <cstdio>
#include <cmath>
using namespace std ;
const int INF = 0x3f3f3f ;
const int N = 1e4+5 ;
int main(){
int t ; scanf("%d",&t) ;
while(t--){
int a,b,c ; scanf("%d%d%d",&a,&b,&c) ;
int mx = 1e9 , aa=a,bb=b,cc=c ;
for(int i=1 ; i<=10005 ; ++i){
for(int j=i ; j<=20005 ; j+=i){
for(int k=j ; k<=40005 ; k+=j){
int sum = abs(a-i)+abs(b-j)+abs(c-k) ;
if(sum < mx){
mx = sum ;
aa=i,bb=j,cc=k ;
}
}
}
}
printf ("%d\n%d %d %d\n",mx,aa,bb,cc) ;
}
return 0 ;
}