Codeforces Round #680 div2 题解(A-D)

题目链接

A. Array Rearrangment

将给定的a,b数组从小到大排序,然后a的第i个匹配b的第n-i-1个,若a[i]+b[n-i-1]>x, 则不合法。

#include <bits/stdc++.h>
using namespace std;
int a[100], b[100];
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		int n, k;
		cin >> n >> k;
		for(int i=0; i<n; i++)
		{
			int temp; cin >> temp; 
			a[i] = temp;
		}
		for(int i=0; i<n; i++)
		{
			int temp; cin >> temp; 
			b[i] = temp;
		}
		sort(a,a+n); sort(b,b+n);
		int flag = 1;
		for(int i=1; i<=n; i++)
		if(a[i-1]+b[n-i]>k) flag = 0;
		if(flag) cout <<"Yes\n";
		else cout <<"No\n";
	}
	return 0;
}

B. Elimination

输入a,b,c,d, 输出max(a+b, c+d)即可。

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		int a,b,c,d;
		cin >> a >> b>> c >> d;
		cout << max(a+b,c+d) << endl;
	}
	return 0;
}

C. Division

题目给定两个整数p, q。要求输出一个尽可能大的数x,满足 p % x = = 0 & x % q ! = 0 p\%x==0 \& x\%q!=0 p%x==0&x%q!=0
如果p%q!=0,那么直接输出p。
否则,我们先对q进行质因数分解,并记录相同的质因数出现的个数。
对q出现的所有不相同的质因数,我们可以称之为f, 我们也要找到质因子f在p中所有质因子出现的次数。
此时我们记质因子f在p中出现n次, 在q中出现m次, 那么 p/(f^(n-m+1)) 将是一个满足 p % x = = 0 & x % q ! = 0 p\%x==0 \& x\%q!=0 p%x==0&x%q!=0的数字。
遍历所有q的不同质因子,找到最大的该数字即可。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100100;
typedef long long ll;
bool isnp[MAXN];
vector<int> primes; // 质数表
vector<int> f;
struct {
	int num, cnt;
} a[100100];
void init(int n) //欧拉筛 
{
    for (int i = 2; i <= n; i++)
    {
        if (!isnp[i])
            primes.push_back(i);
        for (int p : primes)
        {
            if (p * i > n)
                break;
            isnp[p * i] = 1;
            if (i % p == 0)
                break;
        }
    }
}
void func(ll n) //分解质因数 
{
	for(auto p:primes)
	{
		if(n%p==0)
		{
		f.push_back(p);
		n/=p;
		}
		while(n%p==0)
		{
			f.push_back(p);
			n/=p;
		}
	}
	if(n!=1) f.push_back(n);
	int cnt=0;
	for(auto p:f)
	{
		if(p!=a[cnt].num) a[++cnt].num = p, a[cnt].cnt=1, a[0].num++;
		else a[cnt].cnt++;
	}
}

ll sol(ll p,int i)
{
	int rev = 0;
	while(p%(ll)a[i].num==0) 
	{
		p/=a[i].num;
		rev++;
	}
	ll ans = 1;
	for(int j=1; j<=(rev-a[i].cnt+1); j++)
	ans *= a[i].num;
	return ans;
}
int main()
{
	int t;
	cin >> t;
	init(100000);
	while(t--)
	{
		{
			f.clear();
			memset(a, 0, sizeof a);
		}
		ll p, q;
		cin >> p >> q;
		int cnt = 0;
		if(p%q) cout << p << endl;
		else
		{
			func(q);
			ll ans=0x3fffffffffffffff;
			for(int i=1; i<=a[0].num; i++)
			ans = min(ans, sol(p,i));
			cout << p/ans << endl;
		}
	}
	return 0;
}

D Extreme Subtraction

题目大意:
给t组样例。每组样例,包含一个整数n,以及n长度的数组a。
对数组a,是否能通过以下两种操作使得全部元素为0。
操作一,选择数组从开头开始、连续的区间,每个元素减一。
操作二,选择数组从末尾开始、连续的区间,每个元素减一。
解法:

  1. 对a数组进行差分得到数组b。
  2. 取出a[0],并将a[0]与b数组中所有的负数相加。
  3. 判断此时a[0]是否为非负整数,是则可行,输出“Yes",否则不可行,输出”No“。
#include <bits/stdc++.h>
using namespace std;
int a[100100], b[100100];
int main()
{
	int t; cin >> t;
	while(t--)
	{
		int n; cin >> n;
		for(int i=0; i<n; i++) cin >> a[i];
		b[0] = a[0];
		for(int i=1; i<n; i++) b[i] = a[i]-a[i-1];
		int ans = a[0];
		for(int i=1; i<n; i++) if(b[i]<0) ans += b[i];
		if(ans>=0) cout << "Yes\n";
		else cout << "No\n";
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值