A. GCD vs LCM
分析
给一个数n,使满足条件:
a+b+c+d=n,ab的最大公因数为,cd的最小公倍数。
b,c,d值都为1,最大公因数及最小公倍数都为1,a=n-3
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=550;
const ll mod=998244353;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
cout<<n-3<<" 1 1 1"<<endl;
}
return 0;
}
B. Array Cloning Technique
分析
给一个数组,可以通过两个操作,使数组元素相同,分别是复制这个数组和交换复制的数组和原数组两个数,找出最小的操作数。
要使操作数最小,就要找数组中最多的数,这样才能复制和交换更少次。然后模拟复制交换即可。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=550;
const ll mod=998244353;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int main()
{
int t;
cin>>t;
map<int,int> mp;
while(t--)
{
mp.clear();
int n;
cin>>n;
int max=0;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
mp[x]++;
if(mp[x]>mp[max]) max=x;
}
int sum=mp[max];
int ans=0;
while(sum<n)
{
ans++;
if(sum*2>n) ans+=n-sum;
else ans+=sum;
sum*=2;
}
cout<<ans<<endl;
}
return 0;
}
C. Tree Infection
分析
给一个树,每秒可同时进行感染一个顶点,或者让已感染的顶点感染它的兄弟顶点。求最少需要多久。
贪心。尽可能感染有兄弟的顶点,让兄弟顶点互相感染的同时,感染没有办法被兄弟顶点感染的顶点。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=2e5+10;
const ll mod=998244353;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int sum[maxn];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(sum,0,sizeof(sum));
int n;
cin>>n;
sum[n+1]=1;
for(int i=2;i<=n;i++)
{
int x;
cin>>x;
sum[x]++;
}
sort(sum+1,sum+n+2,cmp);
int m;
for(m=1;;m++)
{
if(sum[m]==0)
{
m--;
break;
}
}
for(int i=1;i<=m;i++)
{
sum[i]=sum[i]-m+i-1;
}
sort(sum+1,sum+n+1,cmp);
int ans=m;
int mm;
if(sum[1]>0) mm=1;
else mm=0;
while(1)
{
if(sum[mm]==0) break;
sum[mm]--;
mm=0;
ans++;
for(int i=1;i<=m;i++)
{
if(sum[i]<=0) break;
sum[i]--;
if(sum[mm]<=sum[i]) mm=i;
}
}
cout<<ans<<endl;
}
return 0;
}