Codeforces Round #708 (Div. 2)A,B,C1,C2,E1题解

A题 把从小到大排序再把重复的排到后面

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,a[N],cnt[110];
int main()
{
    
    
	scanf("%d",&t);
	while(t--)
	{
    
    
		memset(cnt,0,sizeof cnt);
		scanf("%d",&n);
		for(int i=1;i<=n;i++)scanf("%d",&a[i]),cnt[a[i]]++;
		int c=0;
		while(c<n)
		{
    
    
			for(int i=0;i<=100;i++)
			{
    
    
				if(cnt[i]>0)
				{
    
    
					cout<<i<<' ';
					cnt[i]--;
					c++;
				}
			}
		}
		puts("");
	}
	return 0;
}

B题 把 a [ i ] a[i] a[i]% m m m,枚举 a [ i ] a[i] a[i],看有没有 a [ j ] = m − a [ i ] a[j]=m-a[i] a[j]=ma[i]
比如 m = 5 , a [ i ] = 2 m=5, a[i]=2 m=5,a[i]=2,看下存不存在 3 3 3
可以 2 3 2 3 2 3…组成一个序列
需特判下 a [ i ] = 0 a[i]=0 a[i]=0 m m m% 2 = = 0 2==0 2==0的情况,把 0 0 0 m / 2 m/2 m/2的分别全部分成一组

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,a[N],cnt[N];
int main()
{
    
    
	scanf("%d",&t);
	while(t--)
	{
    
    
		memset(cnt,0,sizeof cnt);
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i]=a[i]%m,cnt[a[i]]++;
		int ans=0;
		if(m%2==0&&cnt[m>>1])ans++,cnt[m>>1]=0;
		if(cnt[0])ans++,cnt[0]=0;
		for(int i=1;i<=n;i++)
		{
    
    
			int x=a[i];
			if(cnt[m-x]&&cnt[x])
			{
    
    
				ans++;
				if(cnt[x]>cnt[m-x])
				{
    
    
					int mm=cnt[m-x];
					cnt[m-x]=0,cnt[x]-=mm+1;
				}
				else if(cnt[x]<cnt[m-x])
				{
    
    
					int mm=cnt[x];
					cnt[m-x]-=mm+1,cnt[x]=0;
				}
				else cnt[x]=cnt[m-x]=0;
			}
		}
		for(int i=0;i<m;i++)ans+=cnt[i];
		cout<<ans<<'\n';
	}
	return 0;
}

C1题 找规律

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,a[N],cnt[N];
int main()
{
    
    
	scanf("%d",&t);
	while(t--)
	{
    
    
		int n,k;
		cin>>n>>k;
		if((n-1)%2==0)cout<<1<<' '<<(n-1)/2<<' '<<(n-1)/2<<'\n';
		else if(n%3==0)cout<<n/3<<' '<<n/3<<' '<<n/3<<'\n';
		else if(((n-2)/2)&1)cout<<n/4<<' '<<n/4<<' '<<n/2<<'\n';
		else cout<<2<<' '<<(n-2)/2<<' '<<(n-2)/2<<'\n';
	}
	return 0;
}

C2题 每次输出1,再 n n n- -, k k k- -,直到 k = 3 k=3 k=3,然后和C1一样的做法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,a[N],cnt[N];
int main()
{
    
    
	scanf("%d",&t);
	while(t--)
	{
    
    
		int n,k;
		cin>>n>>k;
		while(k>3)
		{
    
    
			n--,k--;
			cout<<1<<' ';
		}
		if((n-1)%2==0)cout<<1<<' '<<(n-1)/2<<' '<<(n-1)/2<<'\n';
		else if(n%3==0)cout<<n/3<<' '<<n/3<<' '<<n/3<<'\n';
		else if(((n-2)/2)&1)cout<<n/4<<' '<<n/4<<' '<<n/2<<'\n';
		else cout<<2<<' '<<(n-2)/2<<' '<<(n-2)/2<<'\n';
	}
	return 0;
}

E1题 分解质因数,令 a [ i ] = p 1 k 1 + p 2 k 2 + . . . + p t k t a[i]=p_1 ^{k_1}+p_2 ^{k_2}+...+p_t ^{k_t} a[i]=p1k1+p2k2+...+ptkt
再把偶次幂的去掉就行了,
比如样例 18 6 2 4 1
把偶次幂去掉后 2 6 2 0 0
遍历一遍,如果这个数在前面出现过,那么 a n s + + , m p ans++,mp ans++mp清空, m p mp mp再把当前值存下
记得线性筛,不然会T

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int t,n,k,a[N],prim[N];;
unordered_map<int,bool>mp;
bool vis[N];
void init(){
    
    
	int cnt=0;
	for(int i=2;i<=10000;++i)
	{
    
    
	    if(!vis[i])prim[++cnt]=i;
	    for(int j=1;prim[j]<=10000/i;++j)
	    {
    
    
	        vis[i*prim[j]]=1;
	        if(i%prim[j]==0)break;
	    }
	}
}
int main()
{
    
    
	scanf("%d",&t);
	init();
	while(t--)
	{
    
    
		mp.clear();
		scanf("%d%d",&n,&k);
		for(int i=1;i<=n;i++)
		{
    
    
			int x;
			a[i]=1;
			scanf("%d",&x);
			for(int j=1;prim[j]<=x/prim[j];j++)
			{
    
    
				int cnt=0;
				while(x%prim[j]==0)x/=prim[j],cnt++;
				if(cnt&1)a[i]*=prim[j];
			}
			if(x>1)a[i]*=x;
		}
		int ans=0;
		mp[a[1]]=1;
		for(int i=2;i<=n;i++)
		{
    
    
			if(mp.count(a[i]))
			{
    
    
				ans++;
				mp.clear();
			}
			mp[a[i]]=1;
		}
		if(mp.count(a[n]))ans++;
		cout<<ans<<'\n';
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46001550/article/details/114960216
今日推荐