Codeforces Round #873 (Div. 1 & 2) Editorial

文章介绍了几个编程题目的解题思路,包括如何利用数字能被整除的特性构建序列,找到满足条件的最小公倍数,以及如何排序数组以满足特定条件。核心是算法设计和数组操作的应用。
摘要由CSDN通过智能技术生成

A 这个题目的关键是:谁都知道1可能被所有的数字整除,但是如何利用好这一点在于第一个位置,我们可以想法什么就放什么,然后在逐步增加第一个位置的值 从零开始,一直到整的总和可以被n整除为止

当然这里还有一个神奇的事情,那就是当数字都是偶数的时候,是完全符合要求的:

#include <bits/stdc++.h>
 
using namespace std;
 
int main() {
    
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
 
    int t;
    cin >> t;
    while (t--) {
    	int n;
    	cin >> n;
    	for (int i = 1; i <= n; i++) cout << i * 2 << " ";
    	cout << "\n";
    }
}

第一个的正常做法:      

#include <iostream>
#include <algorithm>
#include <cstring>
#include <bits/stdc++.h>

using namespace std;
const int N = 210;
int sum[N];

int main(){
	int t;cin >> t;
	while(t --){
		for(int i = 1;i <= 200;i ++)sum[i] = i,sum[i] += sum[i - 1];
		int n;cin >> n;
		if(n == 1) {
			cout << 1 << endl;
			continue;
			
		}
		if(n ==  2){
			cout << 2 << " " << 4 ;
			cout << endl;
			continue;
		}
		int x = sum[n] - 1;
		int y = 0;
		while(x % n != 0){
			y ++;
			x ++;
		}
		cout << y << " ";
		for(int i = 2;i <= n;i ++) cout << i << " ";
		cout << endl;
	}

	return 0;
}

B这个题目的正确思路是这样的,如果我在六号的位置上,我想去一号位置,最大我可以一下到六,但是呢,我们没有这么牛逼的方式,我们可以选择1 2 3 ,为什么可以选择,因为这全是6的倍数,那么对于所有的数字,都有这样的特点,所以我们要满足所有的点可以到达,还得满足最小,这就是最小公倍数

//我刚开始想的是 取决于每个数字的复杂程度 其实这样想有点步入正轨了 
//但是没有完全不如正轨
//正确的思路是这样的 
//最大就是两点之间的距离 能不能小一点呢 如果小一点的话肯定也是约数关系
//所以就是最大公约数
#include<iostream>
#include <cstring>
#include <algorithm>
 
using namespace std;
const int N = 1e5 + 10;
int a[N];
 
int main(){
	int t;cin >> t;
	while(t --){
		int n;cin  >> n;
		for(int i = 1;i <= n;i ++) cin >> a[i];
		int res = 0;
		for(int i = 1;i <= n;i ++)
		res = __gcd(res,abs(i - a[i]));
		cout << res << endl;
	}
}

C题意:有两个数组,我们现在需要对两个数组进行排序,使得第一个数组的所有对应位置上的数字都大于第二个数组,问有几种方式,咋一听很难,但是这个题目很简单,超级无敌简单:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;

struct testcase{
	testcase(){
		int n; cin >> n;
		vector<int> a(n);
//      2 4 5 6 8 9
//      6 5 4 3 1 1
//      4 1 5 6 3 1
		for (int i=0; i<n; i++) cin >> a[i];
		sort(a.begin(), a.end());//对数组a排序的作用是 非常方便的找到 有几个数字能用(二分肯定是要sort的)
		vector<int> b(n);
		for (int i=0; i<n; i++) cin >> b[i];
		sort(b.begin(), b.end(), greater<>());//这里的思想非常的巧妙 非常的好
		ll result = 1;
		for (int i=0; i<n; i++){
			int geq_count = a.size() - (upper_bound(a.begin(), a.end(), b[i]) - a.begin());
			
			result = result * max(geq_count - i, 0) % MOD;//这里注意两点 一个是mod不要在最后mod,我们在计算当中mod;二是就是出现负数不合格了,直接赋值为零就可以了
			if(result == 0)break;
		}
		cout << result << "\n";
	}
};

signed main(){
	cin.tie(0)->sync_with_stdio(0);
	
	int t; cin >> t;
	while (t--) testcase();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

codeforces1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值