最近在刷牛客的时候遇见了这个手套问题:我们一起来看一看
链接:
https://www.nowcoder.com/questionTerminal/365d5722fff640a0b6684391153加粗样式e58d8?pos=2&orderByHotValue=0&done=0
来源:牛客网
在地下室里放着n种颜色的手套,手套分左右手,但是每种颜色的左右手手套个数不一定相同。A先生现在要出门,所以他要去地下室选手套。但是昏暗的灯光让他无法分辨手套的颜色,只能分辨出左右手。所以他会多拿一些手套,然后选出一双颜色相同的左右手手套。现在的问题是,他至少要拿多少只手套(左手加右手),才能保证一定能选出一双颜色相同的手套。
给定颜色种数n(1≤n≤13),同时给定两个长度为n的数组left,right,分别代表每种颜色左右手手套的数量。数据保证左右的手套总数均不超过26,且一定存在至少一种合法方案。
输入
4,[0,7,1,6],[1,5,0,6]
输出
返回:10(解释:可以左手手套取2只,右手手套取8只)
思路
这个题目给了我们手套的颜色数,和每种颜色的左右手套的个数。让我们求出拿到一副颜色相同的手套最坏情况下所要拿的手套个数。我们要保证所有要拿到一副手套还要确定手套个数最少。我们只要拿出一只手的全部颜色(总数-最小的颜色数+1),另外一只手再去拿任意一只就能成功(但是在题目中出现了某一种手套的颜色为0的个数的情况,这个时候我们就必须必须把为0的个数统计起来,我看了好多博客写在两边有0的情况下说的很迷,只要一边有0,我们的最颜色数就不考虑这个数)
代码来看:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class gloves {
public:
int find(int n, vector<int> left, vector<int> right) {
int sum = 0;//统计两边的一边为0的时另一边的手套数目的总和
int ls = 0, rs = 0;
int l_min = INT_MAX, r_min = INT_MAX; //边界值是26
for (int i = 0; i<n; i++)
{
if (left[i] * right[i] == 0)
{
sum += left[i] + right[i]; //左边或者右边没有的时候需要全部拿走(最差结果)
}
else
{
ls += left[i]; //计算左边除了为零的那几组的总和
rs += right[i]; //右边总和
l_min = min(l_min, left[i]); //左边的最小值,右边为0时没有,左边的数也没有计算在内
r_min = min(r_min, right[i]); //右边的最小值
}
}
return sum + min(ls - l_min + 1, rs - r_min + 1) + 1; //为0手套颜色的数量+最小拿出的数量+任意的1
}
};