欢迎来我的博客看看!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 1≤t≤100
- 1 ≤ n ≤ 1 0 3 1\le n \le 10^3 1≤n≤103
- 1 ≤ a i ≤ 4 1 \le a_i\le 4 1≤ai≤4
输出
输出 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 1≤n≤105
- 1 ≤ s , t ≤ n 1\le s,t\le n 1≤s,t≤n
- 1