Codeforces Round #708 (Div. 2)
作者:互联网
文章目录
- A、Meximization
- B、M-arrays
- C1、 k-LCM (easy version)
- C2、 k-LCM (hard version)
- D、Genius
- E1、 Square-free division (easy version)
- E2、Square-free division (hard version)
A、Meximization
题目大意:MEX[ i ]代表数组前 i 个数中没有出现的最小非负数,给一个数组,重新排列使他MEX的和最小。
解题思路:对于所有出现的数字从小到大(可以尽快提高MEX的值),再输出重复的数。
AC代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <climits>
#include <cmath>
#include <set>
typedef long long ll;
const int maxn=1e2 + 5;
const int INF=0x3f3f3f3f;
using namespace std;
int t,q,n,cnt[maxn];
int main()
{
cin>>t;
while(t--){
cin>>n;
memset(cnt,0,sizeof(cnt));
for(int a=0;a<n;a++)
{
cin>>q;
// cout<<q<<endl;
cnt[q]++;
}
// cout<<cnt[4]<<endl;
for(int a=0;a<=100;a++){
if(cnt[a]>0)
{
cout<<a<<" ";
cnt[a]--;
}
}
for(int a=0;a<=100;a++){
while(cnt[a]>0)
{
cout<<a<<" ";
cnt[a]--;
}
}
cout<<endl;
}
return 0;
}
B、M-arrays
题目大意:多组输入,对于每组给出 n 个数和 m 把n个数分成多个序列使每个序列的相邻元素和都是m的倍数,或者只有一个元素。
解题思路:对于输入的数,不管他的值是多少对于我们有用的是他模m的余数是多少,只要连个数的模m余数的和是m那他们的和就可以被m整除,所以首先使 a[ i ] %=m,由于m<=1e5 ,即 a[ i ] %m <= 1e5 所以可以开个数组来存每个余数的出现次数。
之后是配对,余数m-x 和 x 配对,多余的数没有办法和其他数配对所以只能单独一个序列。要注意的数x-m 和 x配对可以是 ababa 即有一个数的出现此时可以必另一个多一次。
还有一种情况是当m为偶数时,m/2只能和自己配对,所以只要这个数出现了就可以单独用一个序列。
AC代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <climits>
#include <cmath>
#include <set>
typedef long long ll;
const int maxn=1e5 + 5;
const int INF=0x3f3f3f3f;
using namespace std;
int n,m,t,q;
int arr[maxn];
int main()
{
cin>>t;
while(t--)
{
// cout<<(666%1)<<endl;
memset(arr,0,sizeof(arr));
cin>>n>>m;
for(int a=0;a<n;a++)
{
cin>>q;
q%=m;
arr[q]++;
}
// cout<<arr[0]<<endl;
int ans=0;
if(arr[0])ans++;
int tmp=0;
for(int a=1;a<m/2;a++)
{
if(arr[a]||arr[m-a])
{
// cout<<"add "<<a<<endl;
tmp = abs(arr[a]-arr[m-a]);
if(tmp)tmp--;
ans+=(tmp+1);
}
}
if(m%2==0)
{
if(arr[m/2])
ans++;
}else
{
if(arr[m/2]+arr[m/2+1] && m!=1)
{
tmp = abs(arr[m/2]-arr[m/2+1]);
if(tmp)tmp--;
ans+=(tmp+1);
// cout<<"add 1222"<<endl;
}
}
cout<<ans<<endl;
}
return 0;
}
C1、 k-LCM (easy version)
题目大意:多组输入给出n和k(k始终为3)求k个数,使其和为 n 最小公倍数不大于 n/2 。
解题思路:如果 n%4=0那么直接输 n/2 n/4 n/4最大公倍数是n/2
如果 n%2=0 && n%4!=0 输出 2 n/2-1 n/2-1 最大公倍数是 n/2-1
如果 n数奇数 那么直接输 1 n/2 n/2 最大公倍数是n/2
AC代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <climits>
#include <cmath>
#include <set>
typedef long long ll;
const int maxn=1e3 + 5;
const int INF=0x3f3f3f3f;
using namespace std;
int n,k,t;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>k;
int ans=0;
if(n%2==0 && n/2%2==0)
{
cout<<n/2/2 <<" "<<n/2/2 <<" "<<n/2<<endl;
}
else if(n%2==0 && n/2%2==1)
{
cout<<2<<" "<< n/2-1 <<" " << n/2-1<<endl;
}else
{
cout<<1<<" "<<(n-1)/2<<" "<<(n-1)/2<<endl;
}
}
return 0;
}
C2、 k-LCM (hard version)
题目大意:题目和c1是一样的区别是这里k不一定是3
解题思路:输出k个1 就可以把问题转化为 c1 此时n为n-(k-3) ,k为3
AC代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <climits>
#include <cmath>
#include <set>
typedef long long ll;
const int maxn=1e3 + 5;
const int INF=0x3f3f3f3f;
using namespace std;
int n,k,t;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>k;
int ans=0;
n-=(k-3);
if(n%2==0 && n/2%2==0)
{
cout<<n/2/2 <<" "<<n/2/2 <<" "<<n/2;
}
else if(n%2==0 && n/2%2==1)
{
cout<<2<<" "<< n/2-1 <<" " << n/2-1;
}else
{
cout<<1<<" "<<(n-1)/2<<" "<<(n-1)/2;
}
for(int a=0;a<k-3;a++)
{
cout<<" "<<1;
}
cout<<endl;
}
return 0;
}
D、Genius
待补
E1、 Square-free division (easy version)
题目大意:给一个数组,最少可以把它划分成多少段,使每一段中的任意两个数的积不是完全平方数。
解题思路:对于每一个数把它因子中的完全平方数数除掉,那么剩下的就是单个素数的积。和他不能在一个片段的数就是等于它的数。标记每一个数的下一个不能共存的数的位置之后从头开始遍历,将其划分
AC代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <climits>
#include <cmath>
#include <set>
typedef long long ll;
const int maxn=2e5 + 5;
const int maxp = 1e4;
const int INF=0x3f3f3f3f;
using namespace std;
int n,k,t,arr[maxn];
bool vis[maxn];
map<int,bool> ou;
bool isq(int i)
{
int q = sqrt(i);
return q*q==i;
}
ll p[maxp],pcnt;
int num[maxp];
void getP()
{
pcnt=0;
memset(num,1,sizeof(num));
for(int a=2;a<=maxp;a++)
{
if(num[a])p[pcnt++] = a;
for(int b=0;b<pcnt;b++)
{
if(a*p[b]>maxp)break;
num[a*p[b]] = false;
if(a%p[b]==0)break;
}
}
}
int main()
{
getP();
for(int a=0;a<pcnt;a++)
{
p[a]*=p[a];
}
cin>>t;
while(t--)
{
ou.clear();
cin>>n>>k;
int ans=0;
for(int a=0;a<n;a++)
{
cin>>arr[a];
for(int b=0;b<pcnt && arr[a]>=p[b];b++)
{
if(arr[a]%p[b]==0)arr[a]/=p[b];
}
}
for(int a=0;a<n;a++)
{
if(ou[arr[a]])
{
ans++;
ou.clear();
}
ou[arr[a]]=1;
}
cout<<ans+1<<endl;
}
return 0;
}
E2、Square-free division (hard version)
待补题
标签:arr,708,cout,int,Codeforces,cin,const,Div,include 来源: https://blog.csdn.net/xkyy66/article/details/114967822