Codeforces Round #725 (Div. 3) A~C,F题

本文介绍了三道编程竞赛题目及其解决方案。A题是寻找最少摧毁次数以消除最轻和最重的石头;B题涉及糖果的公平分配,要求找出重新分配时最小的选取人数;C题是计算序列中满足特定条件的数对数量。通过排序和二分查找等算法,分别给出了高效解答。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Codeforces提交链接

A:Stone Game

题意:
n块石头,排成一行,每块石头拥有不同的重量。
你的任务就是:摧毁当中最轻和最重的那两块石头
摧毁规则:
只能摧毁最左面和最右边的石头。
注意:被摧毁的石头就代表消失。
问最少摧毁几块石头可完成任务。

题解:
找出重量最大和最小的下标。
分三种情况考虑:
1.要么从左到右进行摧毁。
2.要么从右至左进行摧毁。
3.要么两边进行摧毁。

三种情况取最小即为答案。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[1110];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		int maxx=0,minn=1111,xx=1,nn=1;
		for(int i=1;i<=n;i++)
		{
			if(maxx<a[i])
			{
				maxx=a[i];
				xx=i;
			}
			if(minn>a[i])
			{
				minn=a[i];
				nn=i;
			}
		}
		if(xx>nn)	swap(xx,nn);
		int mind=9999;
		mind=min(mind,nn);
		mind=min(mind,n+1-xx);
		mind=min(mind,n+1-xx);
		mind=min(mind,xx+n+1-nn);
		printf("%d\n",mind);
	}
	return 0;
}

B:Friends and Candies

题意:
Polycarp有n个朋友,
初始每个朋友被分配ai个糖果,
但Polycarp觉得每个朋友的糖果数量应该相等,
因此Polycarp想重新分配一次。

他可以挑选任意k个朋友,然后把他们的糖果集中在一起,
这时候,Polycarp会拿着这些糖果进行重新分配。

若分配不能一致,输出-1
若能,输出k的最小值。

题解:
水题。只要找出比平均值大的人有几个即为答案。

代码:

 #include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+1100;
int a[N];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		ll sum=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			sum+=a[i];
		}
		int ave=sum/n;
		if(ave*n!=sum)
			printf("-1\n");
		else
		{
			sort(a+1,a+1+n);
			int p=upper_bound(a+1,a+1+n,ave)-a;
			printf("%d\n",n-p+1);
		}
	}
	return 0;
}

C题: Number of Pairs

题意:
t组样例。
给出3个整数n,l,r
接着给出长度为n的序列.

求该序列有多少对满足下列不等式。
满足:l <= a[i]+a[j] <= r.(1 <= i < j <= n)

题解:

举个例子来说:

5 5 8
5 1 2 4 3

可知:在 i < j 的情况下,一共可以匹配 ( n - 1 ) * n / 2对

即
(5,1),(5,2),(5,4),(5,3)
(1,2),(1,4),(1,3)
(2,4),(2,3)

接着对上述进行调整,保证括号内左边<右边
这不会影响结果。

(1,5),(2,5),(4,5),(3,5)
(1,2),(1,4),(1,3)
(2,4),(2,3)
(3,4)

再调整:

(1,2),(1,3),(1,4),(1,5)
(2,3),(2,4),(2,5)
(3,4),(3,5)
(4,5)

因此排序不会影响结果,还可以利用二分。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N=2e5+1100;
ll a[N];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		ll n,l,r;
		scanf("%lld %lld %lld",&n,&l,&r);
		for(int i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		sort(a+1,a+1+n);
		ll ans=0;
		for(int i=1;i<=n;i++)
		{
			int p1=lower_bound(a+i+1,a+1+n,l-a[i])-a;
			int p2=upper_bound(a+i+1,a+1+n,r-a[i])-a;
			ans+=(p2-p1);
		}	
		printf("%lld\n",ans);
	}
	return 0;
}

D:Another Problem About Dividing Numbers

待补。

F:Interesting Function

题意:
给你L和R,让L一直加1,直至等于R。
计算在这期间:前一个数与后一个数各位不同数量 的累加之和。

题解:
举个例子:

样例:1 100
答案:110

可看做:

  001
  100

在001变化到100时,
只看个位上数字的变化:次数=100-1=99次。
只看十位上数字的变化:次数=10-0=10次,即1,2,3,4,5,6,7,8,9,0.

各位上的数字都遵循上述规律。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll L,R,ans;
void solve()
{
	while(L!=0||R!=0)
	{
		ans+=(R-L);
		L/=10;
		R/=10;
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld %lld",&L,&R);
		ans=0;
		solve();
		printf("%lld\n",ans);
	}
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值