ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #725 (Div. 3)

2021-06-11 18:57:24  阅读:257  来源: 互联网

标签:prime int scanf Codeforces 725 maxn ans Div ll


文章目录


A、Stone Game

传送门


1.思路

先找到最大值和最小值的下标,然后分3类讨论(只操作左端点,只操作右端点,和两端都操作)取最小值即可。


2.参考代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn];
int n;
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int maxx = INT_MIN, maxi = 0, minn = INT_MAX, mini = 0;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &a[i]);
			if (a[i] > maxx)
			{
				maxx = a[i];
				maxi = i;
			}
			if (a[i] < minn)
			{
				minn = a[i];
				mini = i;
			}
		}
		int sum1 = 0, sum2 = 0, sum3 = 0;
		sum1 = max(maxi, mini);
		sum2 = n - min(maxi, mini) + 1;
		sum3 = min(maxi, mini) + n - max(maxi, mini) + 1;
		printf("%d\n", min(sum1, min(sum2, sum3)));
	}
}



B、Friends and Candies

传送门


1.思路

要将每个a[i]值都变成相同,则需要将大于平均值的数取出来然后进行分配,知道这点就能轻松AC,但是注意要判断输出-1的情况(a[i]的和不能被n整除)。


2.参考代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
ll a[maxn];
ll sum;
ll n;
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		sum = 0;
		scanf("%lld", &n);
		for (int i = 1; i <= n; i++)
		{
			scanf("%lld", &a[i]);
			sum += a[i];
		}
		if (sum % n != 0)printf("-1\n");
		else
		{
			ll avge = sum / n;
			int ans = 0;
			for (int i = 1; i <= n; i++)
				if (a[i] > avge)ans++;
			printf("%d\n", ans);
		}
	}
}



C、Number of Pairs

传送门


1.思路

要找到有多少对符合条件的数对,则我们可以通过for循环来枚举起点,至于终点要怎么得到呢?

继续for循环?如果继续for循环将喜提TLE,起点确定了来确定符合条件的一段区间可以通过二分来获取。先sort一下,然后二分下标找符合条件的数对对数。

二分可以巧用upper_boundlower_bound。用upper_bound来找到第一个大于**r - a[i]的下标,用lower_bound来找到第一个大于等于l - a[i]**的下标。在两个下标之间的个数就是全部符合条件的个数。注意upper_bound和lower_bound返回下标时可能小于了i,这是我们需要去掉这段区间


2.参考代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
ll a[maxn];
ll n, l1, r1;
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%lld%lld%lld", &n, &l1, &r1);
		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++)
		{
			ll x = upper_bound(a + 1, a + n + 1, r1 - a[i]) - a - 1;
			if (x <= i)continue;
			ans += x - i;
			ll y = lower_bound(a + 1, a + n + 1, l1 - a[i]) - a - 1;
			if (y <= i)continue;
			ans -= y - i;
		}
		printf("%lld\n", ans);
	}
}



D、 Another Problem About Dividing Numbers

传送门


1.思路

这题主要是找到符合a、b转换相同的次数的区间较难。

首先我们可以把a、b的最大公约数求出来。转化的时候就是最大公约数gcd可以转换2次,则最多可以转化2*(最大公约数的质因子个数)次。那a/gcd、b/gcd也可转化各自的质因子的个数次。

则转化为相同数的最多次数为2*(最大公约数的质因子个数)+a/gcd的质因子的个数+b/gcd的质因子的个数

最小的地方判断要更加细心,我由于粗心导致WA了两发。首先在ab的地方k一定是不能等于1的。其次ab的时候,最小转化次数为0。a % b ==0|| b % a == 0时,最小转化次数为1,那其余的情况则为2了。


2.参考代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
const int maxn = 1e5 + 10;
ll a, b, k;
ll prime[maxn];
bool vis[maxn];
ll cnt;
ll gcd(ll x, ll y)
{
	return y == 0 ? x : gcd(y, x % y);
}
void Prime()
{
	for (int i = 2; i < maxn; i++)
	{
		if (vis[i] == false) prime[cnt++] = i;
		for (int j = 0; i * prime[j] < maxn; j++)
		{
			vis[i * prime[j]] = true;
			if (i % prime[j] == 0) break;
		}
	}
}
ll solve(ll h)
{
	ll ans = 0;
	for (int i = 0; i < cnt; i++)
	{
		if (prime[i] * prime[i] > h)break;
		if (h % prime[i] == 0)
		{
			ll sum = 0;
			while (h % prime[i]==0)
			{
				h /= prime[i];
				sum++;
			}
			ans +=sum;
		}
	}
	if (h != 1)ans += 1;
	return ans;
}
 
int main()
{
	int t;
	scanf("%d", &t);
	Prime();
	while (t--)
	{
		scanf("%lld%lld%lld", &a, &b, &k);
		if (a == b && k == 1)printf("NO\n");
		else if (a == 1 && b == 1 && k != 0)printf("NO\n");
		else
		{
			ll l, r;
			ll xx = gcd(a, b);
			ll yy = a / xx, zz = b / xx;
			if (a == b)l = 0;
			else if (a % b == 0 || b % a == 0)l = 1;
			else l = 2;
			r = 2 * solve(xx) + solve(yy) + solve(zz);
			if (k >= l && k <= r)printf("YES\n");
			else printf("NO\n");
		}
	}
}



F、Interesting Function

传送门


1.思路

思路极其简单,只需要判断l到r中,每一位数字变化的次数相加即可。(水题放这么后面,cf搞心态呀)


2.参考代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		ll ans = 0;
		ll l, r;
		scanf("%lld%lld", &l, &r);
		while (r)
		{
			ans += r - l;
			r /= 10;
			l /= 10;
		}
		printf("%lld\n", ans);
	}
}



标签:prime,int,scanf,Codeforces,725,maxn,ans,Div,ll
来源: https://blog.csdn.net/qq_54484765/article/details/117824882

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有