数论-寒假

文章目录

  • A - 2023
    • 题意:
    • 题解:
    • 代码:
  • B - Make Almost Equal With Mod
    • 题意:
    • 题解:
    • 代码:
  • C - Insert and Equalize
    • 题意:
    • 题解:
    • 代码:
  • D - Ace Arbiter
    • 题意:
    • 题解:
    • 代码:
  • E - Divide and Equalize
    • 题意:
    • 题解:
    • 代码:

A - 2023

题意:

在一个乘积等于 2023的序列 a中,k数字被删除,留下一个长度 n n n为的序列 b b b。给定生成的序列,找到任何合适的序列并输出从中删除的k个元素,或者输出不存在。

题解:

设删除后该序列的乘积为 a n s ans ans,如果存在则 2023 2023 2023%ans一定等于 0 0 0,且删除的k个元素可为 1 1 1 1 1 1 1 1 1,… 2023 / a n s 2023/ans 2023/ans

代码:

#include
#include
#define int long long

using namespace std;

void solve(){
	int n,m;
	int sum=1;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		int temp;
		
		cin>>temp;
		
		sum*=temp;
	}
	if(2023%sum) cout<<"NO"<<endl;
	else{
		cout<<"YES"<<endl;
		for(int i=0;i<m-1;i++) cout<<"1"<<" ";
		cout<<(2023/sum)<<endl;
	}
}
signed main(){
	int t;
	
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}

B - Make Almost Equal With Mod

题意:

给出一个数组,存在k,使得数组中每个元素都对k取余后,数组中只存在两个数字,输出满足的一个k。

题解:

若数组中既有偶数又有奇数,则k可取2,当 数组只有偶数或者只有奇数,数组每个元素都除以 2 t 2^{t} 2t后,数组就会同时存在奇数和偶数,所以k为2的次方。

代码:

#include
#include
#include
#define int long long
using namespace std;

const int  N=110;
int a[N];
void solve(){
	set<int> se;
	
	int n;
	
	cin>>n;
	
	for(int i=1;i<=n;i++) cin>>a[i];
	
	int i=1;
	while(1){
			se.clear();
			for(int j=1;j<=n;j++) se.insert(a[j]%i);
			if(se.size()==2){
				cout<<i<<endl;
				return;
			}
		i*=2;
	}
}
signed main(){
	int t;
	
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}

C - Insert and Equalize

题意:

给定一个数组,你需要在数组后面再添加一个元素 k k k,然后选定一个 x x x,每次操作选中一个元素加上 x x x,问最少需要多少次操作,可使数组每个元素都相等。

题解:

对数组排序,所有相邻元素之间差值的最大公约数就是 x x x,然后计算出最后操作后数组的总和,减去初始数组的和,两个差值除以x就是答案。

代码:

#include
#include
#define int long long

using namespace std;

const int N=2e5+10;
int a[N];
int gcd(int a,int b){
	return b > 0 ? gcd(b , a % b) : a;
}
void solve(){
	int n;
	int sum=0;
	cin>>n;
	
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
	}
	if(n==1){
		cout<<"1"<<endl;
		return;
	}
	sort(a+1,a+1+n);
	
	int x=a[2]-a[1];
	
	for(int i=3;i<=n;i++) x=gcd(x,a[i]-a[i-1]);
	
	for(int i=n;i>=1;i--){
		if(a[i]-a[i-1]!=x){
			sum+=a[i]-x;
			break;
		}
	}
	cout<<(a[n]*(n+1)-sum)/x<<endl;
}
signed main(){
	int t;
	
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}

D - Ace Arbiter

题意:

Alice和Bob两人打乒乓球十一分制,首先Alice先发两次球,然后Bob发两次球,依次进行,每次发球都会有人得一分,谁发球谁的比分就会在前面,给你按时间顺序的比分,让你判断比分从第几个开始出现错误。

题解:

可通过两人得分的和判断此时进行到第几局,由此可将比分顺序纠正把Alice的比分始终放在前面,然后判断是否合法。

代码:

#include
#include

using namespace std;

const int N=110;
int a[N],b[N];
int main(){
	int n;
	char t;
	int temp=0;
	
	cin>>n;
	
	for(int i=1;i<=n;i++){
		cin>>a[i]>>t>>b[i];
		if((a[i]+b[i])%4==1||(a[i]+b[i])%4==2) swap(a[i],b[i]);
		
	}	
	for(int i=1;i<=n;i++){
		if(a[i]==11&&b[i]==11){
			cout<<"error "<<i<<endl;
			return 0;
		}
		if(a[i]<a[i-1]||b[i]<b[i-1]){
			cout<<"error "<<i<<endl;
			return 0;
		}
		if(temp&&(a[i]>a[i-1]||b[i]>b[i-1])){
			cout<<"error "<<i<<endl;
			return 0;
		}
		if(a[i]==11||b[i]==11) temp=1;
	}
	cout<<"ok"<<endl;
	
	return 0;
}

E - Divide and Equalize

题意:

给出一个数组,每次操作你需要选中数组中的两个元素,一个乘以 k k k,另一个除以 k k k,问经过有限次操作,是否可以使得数组所有元素都相等。

题解:

每次操作,一个数除以 k k k,则该数字少一个因数 k k k,同时另一个元素乘以 k k k,则该数字多一个因数 k k k,总的因数个数不变,因为所有操作完成后,所有元素都相等,所以所有因数个数都可以分给n个元素。

代码:

#include
#include
#include
#define int long long

using namespace std;

void solve(){
	int n;
	map<int,int> mp;
	
	cin>>n;
	
	for(int i=1;i<=n;i++){
		int temp;
		
		cin>>temp;
		
		for(int j=2;j<=temp/j;j++){
			while(temp%j==0){
				mp[j]++;
				temp/=j;
			}
		}
		mp[temp]++;
	}
	for(auto t:mp){
		if(t.first<=1) continue; 
		if(t.second%n){
			cout<<"NO"<<endl;
			return;
		}
	}
	cout<<"YES"<<endl;
}
signed main(){
	int t;
	
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}

你可能感兴趣的:(算法,c++,数据结构)