蓝桥杯-男女搭配

我的代码

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值