Codefoces #868 div2(1/6)

A

思路:
先构造一个数组s[i],s[i]表示i个1能“构造”出几个1。
然后就分别枚举1的个数和-1的个数
例如

 假如有3个位置
 1为0个,-1 为 3个
 1为1个,-1 为 2个

AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define endl "\n"


using namespace std;

const int N=110;
int s[N];

void solve(){
	int n,k;
	cin>>n>>k;
	int cnt_1=0;
	int cnt_2=0;
	int res=0;
	int x=n;
	int flag=0;
	while(n){
		cnt_1=n;
	    cnt_2=x-cnt_1;
		res=s[cnt_1]+s[cnt_2];
		if(res==k){
			flag=1;
			break;
		}
		n--;
	}
	if(flag){
		puts("YES");
		for(int i=1;i<=cnt_1;i++){
			cout<<1<<' ';
		}
		for(int i=1;i<=cnt_2;i++){
			cout<<-1<<' ';
		}cout<<endl;
	}else {
		puts("NO");
	}
	 
}
	


int main(){
	
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	for(int i=2;i<=110;i++){
		s[i]=s[i-1]+i-1;
	} 
	
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	
	
	
	return 0;
}

B
思路:
对于每个数字判断他此时的位置和他应该所在的位置之差的绝对值是否是k的倍数
abs(a[i]-i)%k==0
若是则可以自己交换让他回到正确的位置
否则cnt++
当cnt>2时,输出-1。因为此时表示不合理的位置>2个,就表明通过一次特殊交换还剩一些数字。
当cnt为2时,判断这两个数字交换后是否合理,若合理输出1,否则输出-1
当cnt = 0时,输出0
不存在cnt=1的情况

AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>

#define endl "\n"
using namespace std;

typedef pair<int,int> PII; 

const int N=2e5+10;

int a[N];
void solve()
{
	int n,k;
	cin>>n>>k;
	int cnt=0;
	vector<PII> b;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=n;i++)
	{
		if( abs(a[i]-i)%k==0 ) continue;
		else
		{
			cnt++;
			b.push_back({i,a[i]});
		} 
	}
	if(cnt>2) cout<<-1<<endl;
	else if(cnt==0) cout<<0<<endl;
	else if(cnt==2)
	{
		swap(b[0].first,b[1].first);
		if( (b[0].second-b[0].first) % k ==0 &&(b[1].second-b[1].first)%k ==0)
		{
			cout<<1<<endl;	
		}else cout<<-1<<endl;
	}
	
	
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		solve();
	}
	
	
	return 0;
}

其实只要cnt==2就输出1就好了~
赛时就是这么想的,但不知道代码哪里出问题了。。。。

#include<iostream>
#include<cstring>
#include<algorithm>

#define endl "\n"
using namespace std;

typedef pair<int,int> PII; 

const int N=2e5+10;

int a[N];
void solve()
{
	int n,k;
	cin>>n>>k;
	int cnt=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=n;i++)
	{
		if( abs(a[i]-i)%k!=0 ) cnt++;
	}
	if(cnt==0) cout<<0<<endl;
	else if(cnt>2) cout<<-1<<endl;
	else if(cnt==2) cout<<1<<endl;
	
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		solve();
	}
	
	
	return 0;
}

C

若q 为质数,则qq为强合数
若p,q,r为质数,则p
q*r 为强合数

思路:
对a[i]分解质因数
我们现在要让b数组的长度最长
则就应该先枚举个数为2的质因数,再用3个不同的质因数组成一组(如果找不到)就把当前剩下的质因数乘到已经找到的答案中

AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#define endl "\n"

using namespace std;

const int N=1e3+10;
int a[N];

void solve()
{
	int n;
	cin>>n;
	map<int,int> mp;
	for(int i=1;i<=n;i++)//对于每一个数分解质因数 
	{
		cin>>a[i];
		for(int j=2;j<=a[i]/j;j++)
		{
			if(a[i]%j==0)
			{	
				while(a[i]%j==0)
				{
					mp[j]++;//质数j的个数++ 
					a[i]/=j;
				}
			}
		}
		if(a[i]>1) mp[a[i]]++;
	}
	
	int res=0;
	int cnt=0; 
	for( auto item : mp)
	{
		res+=item.second/2;
		cnt+=item.second%2;
	}
	
	res+=cnt/3;
	cout<<res<<endl;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	
	int T;
	cin>>T;
	while(T--)
	{
		solve();
	}
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值