Codeforces Round #708 (Div. 2)(A~C)
本次终于A了3题(c-1,c-2就算一题啦)
- Meximization
先去重,然后对前面不重复的部分排序,后面的顺序任意即可。一开始用了unique。
后来才发现他并不是前面不重复,将重复的放在后面,而是将前面重复的用后面不重复的元素替换了。固不能用unique,因为数据小,就也没多想,用vis记录是否重复,用temp记录重复的数即可。
AC代码如下:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<set> using namespace std; int t,n,a[105],vis[105],temp[105]; int main(){ scanf("%d",&t); while(t--){ memset(vis,0,sizeof(vis)); memset(temp,0,sizeof(temp)); int cnt=0; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); int temp[105]; sort(a,a+n); for(int i=0;i<n;i++){ if(!vis[a[i]]){ printf("%d ",a[i]); vis[a[i]]=1; }else temp[cnt++]=a[i]; } for(int i=0;i<cnt;i++) printf("%d ",temp[i]); printf("\n"); } return 0; }
B.M-arrays
题意:将n个数任意分组,其中满足相邻两个数相加能整除m。求最少分组数
我们可以发现如果要满足要求,则相邻两个数相加模m=0.故对n个数各自模m。
然后记录。若m是8,则将模8=1和模8=7的数组合。如果相等或者相差为1例如171
就可以容纳在一个组,但如果是17111,就必须分三个组。因为171,1,1.
故先模m预处理后,记录模数的出现次数进行判断即可。
AC代码如下:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<set> #define MAXN 100005 using namespace std; int t,n,m,a[MAXN],vis[MAXN]; int main(){ scanf("%d",&t); while(t--){ int ans=0; scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ scanf("%d",&a[i]); a[i]%=m; vis[a[i]]++; } if(vis[0]) ans++; vis[0]=0; for(int i=1;i<m;i++){ if(vis[i]&&vis[m-i]){ ans++; if(vis[i]==vis[m-i]) vis[i]=vis[m-i]=0; else if(vis[i]>vis[m-i]){ vis[i]-=vis[m-i]+1; vis[m-i]=0; ans+=vis[i]; vis[i]=0; }else{ vis[m-i]-=vis[i]+1; vis[i]=0; ans+=vis[m-i]; vis[m-i]=0; } }else if(vis[i]){ ans+=vis[i]; vis[i]=0; } } printf("%d\n",ans); } return 0; }
C1. k-LCM (easy version)
给定n和k。求出k个数满足a1+~+ak=n,lcm(a1,a2~,ak)<=n/2.
在easy version中k等于3.
首先我们观察到当n为奇数时,我们可以拆成1,n/2,n/2。(lcm为n/2)
当n为偶数且不是4的倍数时,拆成2,n/2-1,n/2-1.(lcm为n/2-1)
当n为4的倍数是,拆成n/2,n/4,n/4。(lcm为n/2)
AC代码如下:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<set> #define MAXN 100005 using namespace std; typedef long long ll; int t,n,k; int main(){ scanf("%d",&t); while(t--){ scanf("%d%d",&n,&k); if(n==3) printf("1 1 1\n"); else if(n==4) printf("1 1 2\n"); else if(n%4) printf("%d %d %d\n",(n+1)/2-1,(n+1)/2-1,n&1?1:2); else printf("%d %d %d\n",n/4,n/4,n/2); } return 0; }
C2. k-LCM (hard version)
本题与C1相同,但是3<=k<=n;
由上题的结论,我们可以令(n)4=(n-1)3+1.
即先加上k-3个1,这样剩下还有3个数,令n-(k-3)。那个这个n就用C1的结论就好了。
AC代码如下:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<set> #define MAXN 100005 using namespace std; typedef long long ll; int t,n,k; ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); } ll lcm(ll a,ll b){ return a*b/gcd(a,b);} void solve(int n){ if(n==3) printf("1 1 1 "); else if(n==4) printf("1 1 2 "); else if(n%4) printf("%d %d %d ",(n+1)/2-1,(n+1)/2-1,n&1?1:2); else printf("%d %d %d ",n/4,n/4,n/2); } int main(){ scanf("%d",&t); while(t--){ scanf("%d%d",&n,&k); k-=3; solve(n-k); for(int i=0;i<k;i++) printf("1 "); printf("\n"); } return 0; }