文章目录
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<iostream>
#include<algorithm>
#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<iostream>
#include<algorithm>
#include<set>
#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<iostream>
#include<algorithm>
#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<iostream>
#include<algorithm>
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<iostream>
#include<algorithm>
#include<map>
#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;
}