CF 1497:A-C2

本文分享了Codeforces Round #708 (Div.2)的三道编程题目A、B、C的解题思路和代码实现。A题要求按升序输出数组,重复元素放最后;B题是构造题,找出数组能被m整除的最少分组数;C题分为两种情况,分别处理奇数和偶数n的n-LCM问题。通过分析题目和样例,给出了解题策略和代码实现。
摘要由CSDN通过智能技术生成

Codeforces Round #708 (Div. 2)

A题
B题
C1
C2

A. Meximization

其实说白了,这道题就是把数组按从小到大输出,重复的放在最后
本人用的set,略显复杂

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		set<int> s1;
		multiset<int> s2;//重复的可能不止一个,所以用multiset
		set<int>::iterator it1,it2;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			int x;
			cin>>x;
			if(!s1.count(x)) s1.insert(x);
			else s2.insert(x);
		}
		
		for(it1=s1.begin();it1!=s1.end();it1++) cout<<*it1<<' ';
		
		if(!s2.empty())
		{
			for(it2=s2.begin();it2!=s2.end();it2++) 
			 cout<<*it2<<' ';
		}   
		cout<<endl;
	}
	
	return 0;
 } 

B. M-arrays

一道构造题。
有一个大小为 n n n a [ n ] a[n] a[n]数组,多个数相加能被 m m m整除的话构成一个数组,单独一个也可以单独成为一个数组。问: a [ n ] a[n] a[n]数组最少可以被分成多少个像这样能被m整除的数组? ( 1 ≤ a i ≤ 1 0 9 ) (1≤ai≤10^9) 1ai109
其实我们可以从余数出发。
%m的情况:
1 , 2 , 3...... m − 2 , m − 1 1,2,3......m-2,m-1 1,2,3......m2,m1
那我们就可以1和m-1组成一组,2和m-2组成一组,以此类推。余数为0的归到一组,因为题目要求的是最少组数,这些余数为0不用去带其他人。然后我们就可以发现一些规律。

	for(int i=1;i<=n;i++)
		{
			int x;
			cin>>x;
			mod[x%m]++;
		}

读进来数据时,先把它存在 m o d mod mod数组中
a = m o d [ i ] a=mod[i] a=mod[i],
b = m o d [ m − i ] b=mod[m-i] b=mod[mi]
这样a和b可以凑成一对。
1.如果a和b都不为0,且a和b不是同一个数,那么就是一种。举个例子:比如m为8,i为4,那么m-i也是4,他们只能凑成一种。
2.不然就是 a b s ( m o d [ i ] − m o d [ i − 1 ] ) abs(mod[i]-mod[i-1]) abs(mod[i]mod[i1])(这个我也不知道该怎么解释,反正多走几遍数据就是了)

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,m,ans=0;
		cin>>n>>m;
		int mod[100000]={0};
		
		for(int i=1;i<=n;i++)
		{
			int x;
			cin>>x;
			mod[x%m]++;
		}
		if(mod[0]>0) ans++;
		
		for(int i=1;i<=m/2;i++)
		{
			if(mod[i]&&mod[i]==mod[m-i]) ans++;
			 else ans=ans+abs(mod[i]-mod[m-i]);
		}
		
		cout<<ans<<endl;
	}
	return 0;
}

C1. k-LCM (easy version)

分类讨论的一道题目。
1.n奇数
那么三个数分别是:
n / 2 , n/2, n/2, n / 2 n/2 n/2 1 1 1
2.n为偶数
可以转化为 ( n − 1 ) + 1 (n-1)+1 (n1)+1
n-1是奇数按上面方法分解
最后整合一下就是
n / 2 − 1 , n / 2 − 1 , 2 n/2-1,n/2-1,2 n/21,n/21,2
3.但是还有一些数是例外。
例如8如果按照方法2来分解,就会得到 3 , 3 , 2 3,3,2 3,3,2
12如果按照方法2来分解,就会得到 5 , 5 , 2 5,5,2 5,5,2
这都是不符合要求的。
试了几个,我们发现这些数有这样一个特点:
2 n + 2 ( n 为 奇 数 ) 2n+2(n为奇数) 2n+2(n)
那我们可以进一步写成:
2 ( 2 k + 1 ) + 2 2(2k+1)+2 2(2k+1)+2
化简可得:
4 k + 4 4k+4 4k+4
可见这些数都是4的倍数
其实直接一眼看出来
那我们该怎么办呢?这个时候,样例又给了我们启发:

input: 8 3
output:4 2 2

n / 2 , n / 4 , n / 4 n/2,n/4,n/4 n/2,n/4,n/4多试了几个,就他了!!!

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,k;
		cin>>n>>k;
		if(n%2!=0)
		{
			cout<<n/2<<' '<<n/2<<' '<<1;
			cout<<endl;
		}
		else if(n%4!=0)
		{
			cout<<n/2-1<<' '<<n/2-1<<' '<<2;
			cout<<endl;
		}
		else 
		{
			cout<<n/2<<' '<<n/4<<' '<<n/4;
			cout<<endl;
		}
	}
	return 0;
}

C2. k-LCM (hard version)

数学老师曾经告诉我们:一个题目有多个问,那么只些问之间必然有联系!
C2告诉我不仅有联系,而且可以直接copy
C1我们已经处理了 k = 3 k=3 k=3的情况,那么C2直接套就可以了。 k > 3 k>3 k>3的部分直接输出1,剩下来的 n − ( k − 3 ) = n − k + 3 n-(k-3)=n-k+3 n(k3)=nk+3部分同C1

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,k;
		cin>>n>>k;
		k-=3;
		for(int i=1;i<=k;i++)
		 cout<<"1"<<' ';
		n-=k;
		if(n%2!=0)
		{
			cout<<n/2<<' '<<n/2<<' '<<1;
			cout<<endl;
		}
		else if(n%4!=0)
		{
			cout<<n/2-1<<' '<<n/2-1<<' '<<2;
			cout<<endl;
		}
		else 
		{
			cout<<n/2<<' '<<n/4<<' '<<n/4;
			cout<<endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值