Educational Codeforces Round 66 (Rated for Div. 2)

A - From Hero to Zero

题意:给出n和k,有两种操作,一是n-1 ,二是当n可以整除于k时整除k,问最少的操作次数使n变成0。
题解:直接n一直除于k然后加上中间的差值就行了。

#include 
#include 
#include 
using namespace std ; 
typedef long long ll ; 
int main(){
	int t ; 
	cin >> t ; 
	while(t --){
		ll n , k ; 
		cin >> n >> k ; 
		ll cnt = 0 ; 
		while(n){
			ll m = n ;
			n /= k , ++ cnt ; 
			cnt += m-n*k ; 
		}
		cout << cnt-1 << endl ; 
	}
	return 0 ; 
} 
B - Catch Overflow!

题意:给出n个命令,有三种命令“for” “add” “end” , for后面紧跟着数字x,表示循环x次,多个for为嵌套,end为结束最近的一个for,add是计数当前的执行次数。
题解:模拟,栈顶存放当前的循环次数,end就弹出,add就加上栈顶元素,但是要注意细节,首先是long long 有可能也会爆所以压入栈之前取INF和栈顶的最小值即可,然后就是INF了,它是不超过!!!就是可以等于,我居然没注意到,所以INF设置为232 - 1 , 其实应该设置为232即可,然后一直卡在第7个测试(卡了一个多小时。。。。。。。)

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std ; 
typedef long long ll ;
stack<ll> s ;  
const ll INF = 4294967296 ; 
int main(){
	int t ; 
	cin >> t ; 
	ll f = 1 , cnt = 0 , n = 1 ; 
	string comm ;  
	s.push((ll)1) ; 
	while(t --){
		cin >> comm ; 
		if (comm == "for"){
			cin >> n ;
			s.push(min(INF,s.top()*n)) ; 
		}
		else if (comm == "add"){
			cnt = min(cnt+s.top(),INF) ; 
		}
		else if (comm == "end"){
			s.pop() ; 
		}
	}
	if (cnt == INF)	cout << "OVERFLOW!!!" << endl ; 
	else	cout << cnt << endl ; 
	return 0 ; 
} 
C. Electrification

题意:在一维数轴上给出n个点的坐标和k,然后要求找出一个新点,要求新点的到给定点的距离第k+1大值尽量小。
题解:(偷偷抄大佬题解→)来源
检查靠外的n-k对数:a[i]和a[i+k],找出靠得最近的一对并记录中点即可。

#include 
#define rep1(i,a,b) for(int i=a;i<=b;++i)
const int N = 2e5 + 5 ; 
int a[N] ;  

int main(){
	int n , k , t ;
	scanf("%d",&t) ; 
	while(t --){
		scanf ("%d%d",&n,&k) ;
		int dmin = 0x3f3f3f3f , ans = 0 ;
		rep1(i,1,n)		scanf("%d",&a[i]) ; 
		rep1(i,1,n-k) 
		if (dmin > (a[i+k]-a[i]+1)/2){
			dmin = (a[i+k]-a[i]+1)/2 ;
			ans = (a[i+k]+a[i])/2 ; 
		}
		printf ("%d\n",ans) ; 
	} 
	return 0 ; 
}
D - Array Splitting

题意:给出长度为n的数组,要求分成k个数组,问所有的数组乘上相应的子序列的编号最大为多少。
题解:先求后缀和然后排序再翻转,但是要注意sort的时候不要包含a[1],因为序列每个元素都至少被算过一次。(大佬题解牛逼,是我太菜了),这应该是第一次遇到后缀和的题吧。

#include 
#include 
using namespace std ; 
const int N = 3e5 + 10 ;
typedef long long ll ;  
ll a[N] ;
int main(){
	int n , k ; 
	scanf ("%d%d",&n,&k) ; 
	for(int i = 1 ; i <= n ; ++ i)	scanf ("%lld",&a[i]) ;
	for (int i = n ; i >= 1 ; -- i)
		a[i] += a[i+1] ; //后缀和
	ll ans = 0 ; 
	sort(a+2,a+n+1) ; 
	reverse(a+2,a+n+1) ; 
	for (int i = 1 ; i <= k ; ++ i)
		ans += a[i] ; 
	printf ("%lld\n",ans) ;
	return 0 ; 
}

你可能感兴趣的:(CF)