Codeforces Round #677 (Div. 3)部分题解

目录

A - Boring Apartments

B - Yet Another Bookshelf

C - Dominant Piranha

D - Little Girl and Maximum Sum


A - Boring Apartments

题意:1000之内,如果一个数的全部位数数字相同,则为特殊的数,给一个数,需要输出在它之 前包括它的所有特殊位数之和

做法:前面的数 每四个位数和为10 算一下当前n数字是几 当前n是几位数即可

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		int n , b , ans = 0;
		cin >> n;
		int a = n % 10;
		while(n)
		{
			n /= 10;
			ans ++;
		}
		if(ans == 1) b = 1;
		else if(ans == 2) b = 3;
		else if(ans == 3) b = 6;
		else b = 10;
		cout << (a - 1)* 10 + b << endl;
	}
	return 0;
}

B - Yet Another Bookshelf

题意:给一个01串,你可以移动一些连续的1串,问将他们全部搞到一起(连续)所需要的最小步数

做法:其实也就是求 两个中间的0的个数

方法1

#include<bits/stdc++.h>
using namespace std;
int a[60];
int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		int n , b = 0, flag = 0, res = 0 ;
		cin >> n;
		for(int i = 0 ; i < n ; i ++) cin >> a[i];
		for(int i = 0 ; i < n ; i ++)
		{
			if(a[i] == 1)
			{
				flag = 1;
				res += b;
				b = 0;
			}
			else{
				if(flag == 1) b ++;
			}
		}
		cout << res << endl;
	}
	return 0;
}

方法2

#include<bits/stdc++.h>
using namespace std;
int a[60];
int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		int n , ans = 0;
		cin >> n;
		for(int i = 0 ; i < n ; i ++) cin >> a[i];
		int l = 0 , r = n - 1;
		while(a[l] == 0 && l < n) l ++;
		while(a[r] == 0 && r >= 0) r --;
		for(int i = l + 1 ; i < r ; i ++)
		{
			if(a[i] == 0) ans ++;
		}
		cout << ans << endl;
	}
	return 0;
}

C - Dominant Piranha

题意: 给一个数组,定义一个dominant的数,当且仅当如果一个数左边有数,且比左边的数大,则可以吃掉左边的这个数,右边的同理,吃掉一个数,自己会增加1

做法:要找最大的数,假如最大数旁边的数比它小,则有解,否则就是全相等 无解

#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
int a[N];
int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		int n , res = 0 , ans = 0 ;
		cin >> n;
		for(int i = 0 ; i < n ; i ++) 
		{
			cin >> a[i];
			res = max(res , a[i]);
		}
		for(int i = 1 ; i < n ; i ++)
		{
			if(a[i] == a[0]) ans ++;
		}
		if(ans == n - 1){
			cout << -1 << endl;
			continue;
		}
		for(int i = 0 ; i < n ; i ++)
		{
			if(i == 0 && a[i] == res && a[i + 1] < a[i])
			{
				cout << i + 1<< endl;
				break;
			}
			else if(i == n - 1 && a[i] == res && a[i - 1] < a[i])
			{
				cout << i + 1<< endl;
				break;
			}
			else if(i != 0 && i != n - 1 && a[i] == res &&(a[i - 1] < a[i] || a[i + 1] < a[i]))
			{
				cout << i + 1 << endl;
				break;
			}
		}
	}
	return 0;
}

D - Little Girl and Maximum Sum

题意:给一个数字序列,然后会有m组询问 ,每组询问两个数字 l ,r 表示询问[ l, r ] 的区间      和,问你在询问之前怎么排序,才可以使得m组询问累加的区间和最大。

做法:我们需要记录一下哪个点询问的次数最多,让询问次数最多的那个点值最大即可

我们需要构造差分数组 将差分数组求前缀和,就是对应i位置出现次数的问题

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
long long a[N] , s[N];
int main()
{
	long long n, q , sum = 0;
	cin >>  n >> q;
	for(int i = 1 ; i <= n ; i ++) cin >> a[i];
	sort(a + 1 , a + 1 + n);
	while(q --)
	{
		long long l , r;
		cin >> l >> r;
		s[l] ++;
		s[r + 1] --;
	}
	for(int i = 1 ; i <= n ; i ++) s[i] += s[i - 1];
	//for(int i = 1 ; i <= n ; i ++) cout << s[i] << " ";
	sort(s + 1 , s + 1 + n);
	for(int i = 1 ; i <= n ; i ++) sum += a[i] * s[i];
	cout << sum << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值