我的代码
#include <stdio.h>
#include <stdlib.h>
long long maxGroup(long long n,long long m,long long k){
if(n > 2*m){//如果男生多
//把多余的男生送走
k = k - (n - 2*m);
//如果k还大于零
if(k > 0){
int count = 1;
while((k -count*3) > 0){//按照小组送人
count++;
}
return m - count;
}else{
return m;
}
}
//如果女生多
else if(n < 2*m){
k = k - n%2 - (m - n/2);//把多余的女生和落单的男生送走
//如果k还大于零
if(k > 0){
int count = 1;
//按小组送人
while((k -count*3) > 0){
count++;
}
return n/2 - count;
}
//k已经小于0
else{
return n/2;
}
}
else{
return m;
}
}
int main(int argc, char *argv[])
{
// 请在此输入您的代码
int T;
scanf("%d",&T);//T组数据
for(int i = 0;i < T;i++){
long long N,M,K;
scanf("%lld %lld %lld",&N,&M,&K);//N名男生,M名女生,两男一女参加比赛
long long result = maxGroup(N,M,K);
printf("%lld\n",result);
}
return 0;
}
这个思路是对的,但是时间复杂度高,过不了。
答案代码
方案一:
如果不考虑送走的同学,如果男女比例正好是2:1,那么正好组 t 队。否则,就会受限于人数较少的。也就是min(n,2*m)。组完队还余下n+m-3*t。
如果考虑送走k名同学,要让组队数最大,这送走的k名同学要尽可能不影响能组队的同学。
即:如果k < n+m- 3* t。也就是要送走的人没有余下的人多,直接返回 t 。
否则,返回(m+n-k)/3;因为一定会拆散已经组队的,余下的1或2人因为向下取整舍弃了。
#include <iostream>
using namespace std;
int main() {
int T;
cin>>T;
while (T--) {
int n,m,k;
cin>>n>>m>>k;
int t = min(n, m*2)/2;
if (n+m-t*3 >= k)
cout<<t<<'\n';
else
cout<<(n+m-k)/3<<'\n';
}
return 0;
}
方案二:分析思路:分配的目标就是完成3种情况:1.男生组队完成,女生人数多。2.女生组队完成,男生人数多。3. 男女比例刚好。
以分配完后男女比例刚刚好为基准。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int T;
scanf("%d",&T);
int a[1000000];
for(int i=0;i<T;i++)
{
int x1,x2,x3,y;
scanf("%d %d %d",&x1,&x2,&x3);
y=(x1+x2-x3)/3;
//先假设人数刚刚好
a[i]=y;
//就算男生全留下来男生人数也不足以以完美人数组队,也就是男生人数很少,那么最后组队数就是n/2
if(x1<2*y)
a[i]=x1/2;
//如果女生全留下来也不足以以完美人数组队,最后组数就是女生人数
if(x2<y)
a[i]=x2;
}
for(int i=0;i<T;i++)
{
printf("%d\n",a[i]);
}
return 0;
}