Codeforces Round #624 (Div. 3)

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 ; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值