字节跳动 秋招 2023.10.22 编程题目与题解

欢迎来我的博客看看!https://ujimatsu-chiya.github.io/

1、小红的赛车队

假设有 n n n个赛车队参加一场比赛,每个赛车队的车辆数为 a i a_i ai辆,要将这 n n n个赛车队分成小组,每个小组里的车辆总数不超过 4 4 4辆,并且不能把赛车队拆开。问最少需要多少个小组。

输入

一行一个整数 t t t,表示数据组数。

每组数据第一行一个整数 n n n,表示赛车队数。

接下来一行 n n n个整数 a i a_i ai,表示每个赛车队的车辆数。

  • 1 ≤ t ≤ 100 1 \le t \le 100 1t100
  • 1 ≤ n ≤ 1 0 3 1\le n \le 10^3 1n103
  • 1 ≤ a i ≤ 4 1 \le a_i\le 4 1ai4

输出

输出 t t t行,每行一个整数,表示最少需要的小组数。

样例

输入:
1
4
1 2 3 4

输出:
3

提示:
前两个车队一组,第三个车队一组,第四个车队一组即可。

解答

本题可以使用贪心的思想进行解决。

可见, 4 4 4辆一队的队伍无法和其它队伍成组,必须自己成组。 3 3 3辆一队的队伍参加组合,要么自己成组,要么带上一个 1 1 1辆一队的车队。

如此,处理完 4 4 4辆一队和 3 3 3辆一队的车队,剩下 2 2 2辆一队和 1 1 1辆一队的车队。为了尽量减少成组数量,让 2 2 2辆一队的车队两个两个组合。如果 2 2 2辆一队的车队还剩下一个,那么可以至多带上 2 2 2 1 1 1辆一队的车队。剩下的 1 1 1辆一队的车队直接尽可能地进行组合,如果这时仍然有 c c c 1 1 1辆一队的车队,那么至少还需要组成 ⌈ c / 4 ⌉ \lceil c/4\rceil c/4个组。

代码

# include <bits/stdc++.h>
using namespace std;

int c[7];
int solve(){
   
    memset(c,0,sizeof(c));
    int n,x;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
   
        scanf("%d",&x);++c[x];
    }
    int ans=c[4]+c[3];
    c[1]=max(0,c[1]-c[3]);
    ans+=c[2]>>1;
    if(c[2]&1){
   
        ++ans;
        c[1]=max(0,c[1]-2);
    }
    ans+=(c[1]+3)/4;
    return ans;
}
int main(){
   
    int T;
    scanf("%d",&T);
    while(T--){
   
        printf("%d\n",solve());
    }
}

2、小红走迷宫

小红和朋友被困在了迷宫里,迷宫有 n n n个传送阵,每个传送阵都有一个编号 i i i(编号从 1 1 1 n n n),编号为 i i i的传送阵会将小红传送到编号为 a i a_i ai的传送阵。小红最初在编号为 s s s的传送阵,朋友最初在编号为 t t t的传送阵,小红和朋友都可以通过传送阵传送,每次传送都会花费一分钟(两人可以同时传送)。现在小红想知道,小红和朋友最少需要多少分钟才能在同一个传送阵里见面,如果不能见面,输出 − 1 -1 1

输入

第一行输入三个整数 n , s , t n,s,t n,s,t,表示传送阵的数量,小红最初所在的传送阵编号,朋友最初所在的传送阵编号。

第二行输入 n n n个整数 a i a_i ai,表示编号为 i i i的传送阵会将小红传送到编号为 a i a_i ai的传送阵。

  • 1 ≤ n ≤ 1 0 5 1\le n\le 10^5 1n105
  • 1 ≤ s , t ≤ n 1\le s,t\le n 1s,tn
  • 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值