cf1823

发布时间 2023-05-04 20:17:53作者: viewoverlook

A. A-characteristic

题目链接
由于出现数字只可能是1或-1,那么假设数列全为-1,依次枚举1出现的个数,可以得出结论不是所有数字都有答案的,由于会有重复数字出现,只需要枚举1的个数x<=n/2即可。

// Problem: A. A-characteristic
// Contest: Codeforces - Codeforces Round 868 (Div. 2)
// URL: https://codeforces.com/contest/1823/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<stack>
#include<vector>
#include<map>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long LL;
const int N=110;
int t,n,k;
int res[N];
bool cal(int l,int r){
	if(l*(l-1)/2+r*(r-1)/2==k){
		for(int i=1;i<=l;i++) res[i]=1;
		for(int i=l+1;i<=n;i++) res[i]=-1;
		return true;
	}
	return false;
}
bool check(int x){
	int mid=x>>1;
	for(int i=x;i>=mid;i--){
		if(cal(i,x-i)){
			return true;
		}
	}
	return false;
}
int main(){
	cin>>t;
	while(t--){
		cin>>n>>k;
		if(check(n)){
			puts("YES");
			for(int i=1;i<=n;i++){
				cout<<res[i]<<" ";
			}
			puts("");
		}else{
			puts("NO");
		}
	}
	return 0;
}

B. Sort with Step

题目链接
只能交换相隔k个位置的数字,假如k为1,那么可以看作冒泡排序必然有解
k>1时,将数组按照下标i分组,i%k0的为一组,i%k1的为一组,...,i%k==k-1的为一组,要想可以按照递增序列上升,同时由于数字x<n,且只会出现一次。所以如果不先更换一组数据就有解的话,同一组内的数字对k取模的结果必然一致。不一致的话当不一致的数字为2时,可以交换一次得到解,否则无解。

// Problem: B. Sort with Step
// Contest: Codeforces - Codeforces Round 868 (Div. 2)
// URL: https://codeforces.com/contest/1823/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<stack>
#include<vector>
#include<map>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long LL;
const int N=2e5+10;
int t,n,k;
int p[N],tmp[N];
vector<int> q[N];
LL getnum(int l,int r){
	if(l>=r) return 0;
	int mid=(l+r)>>1;
	LL ans=getnum(l,mid)+getnum(mid+1,r);
	int i=l,j=mid+1,cnt=0;
	while(i<=mid&&j<=r){
		if(p[i]<=p[j]) tmp[cnt++]=p[i++];
		else{
			ans+=mid-i+1;
			tmp[cnt++]=p[j++];
		}
	}
	while(i<=mid) tmp[cnt++]=p[i++];
	while(j<=r) tmp[cnt++]=p[j++];
	for(i=l,j=0;i<=r;i++,j++){
		p[i]=tmp[j];
	}
	return ans;
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&k);
		for(int i=0;i<k;i++){
			q[i].clear();
		}
		for(int i=1;i<=n;i++){
			scanf("%d",&p[i]);
			q[i%k].push_back(p[i]);
		}
		if(k==1){
			puts("0");
			continue;
		}
		int res=0;
		for(int i=0;i<k;i++){
			// sort(q[i].begin(),q[i].end());
			// for(int j=0;j<q[i].size();j++){
				// p[i+j*k]=q[i][j];
				// cout<<q[i][j]<<" ";
			// }
			// cout<<endl;
			for(int j=0;j<q[i].size();j++){
				if(q[i][j]%k!=i) res++; 
			}
		}
		// LL res=getnum(1,n);
		// cout<<res<<endl;
		// for(int i=1;i<=n;i++){
			// cout<<p[i]<<" ";
		// }
		// cout<<endl;
		if(res==0) puts("0");
		else if(res==2) puts("1");
		else puts("-1");
	}

	return 0;
}

C. Strongly Composite

题目链接
比赛的时候没做出来但是思路对的,先贴代码

// Problem: C. Strongly Composite
// Contest: Codeforces - Codeforces Round 868 (Div. 2)
// URL: https://codeforces.com/contest/1823/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<stack>
#include<vector>
#include<map>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long LL;
const int N=1010,M=1e5+10;
int T;
int n,k;

int main(){
	/*
	res
	暂时想出来的思路是计算出所有乘数中每个质数的数量,
	然后同一个素数下每两个组合,直至每个素数均剩下0或1个,res+=每个素数的数量/2
	然后计算剩余个数为1的素数的个数count如果可以整除3那么res+=count/3,否则就看乘积是不是强合数,是的话res=1,不是res=0
	*/
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		map<int,int> q;
		for(int i=0;i<n;i++){
			int x;
			scanf("%d",&x);
			for(int j=2;j<=x/j;j++){
				while(x%j==0){
					x/=j;
					q[j]++;
				}
			}
			if(x!=1) q[x]++;
		}
		int res=0,rem=0;
		for(PII p:q){
			int num=p.x;
			int cnt=p.y;
			res+=cnt/2;
			rem+=cnt%2;
		}
		res+=rem/3;
		printf("%d\n",res);
	}

	return 0;
}

思路证明:对于一个强合数x,对其进行因式分解x=\(d^{p_1}_{1}\)\(d^{p_2}_{2}……\)\(d^{p_{m-1}}_{m-1}\)\(d^{p_m}_{m}\),那么x的因子数量为D=$\prod_{i=1}^m{(d_i+1)} \( 数字的质因子个数为m,合因数的个数为D-m-1.x是强合数m<=D-m-1即2*m+1<=D,由于\)d_i$+1>=2,那么D>=\(2^m\)
对于强合数的一个弱条件,2*m+1<=\(2^m\),当m为1或2时不成立其余成立,那么由于D>=\(2^m\),所以当m为1或2时,x为强合数
即如果是一个强合数,质因子个数大于等于3
接下来找出所有数列中的质因子得到(\(p^i\),\(c^i\)),前为质因子,后为所有数中质因子个数。
最优策略是对于同一质因子求\(\sum_i{ci/2}\),剩下个数r=\(\sum_i(ci\%2)\)
res+=\(\sum_i{ci/2}\)+r/3即可