题目描述:
在地下室里放着n种颜色的手套,手套分左右手,但是每种颜色的左右手手套个数不一定相同。A先生现在要出门,所以他要去地下室选手套。但是昏暗的灯光让他无法分辨手套的颜色,只能分辨出左右手。所以他会多拿一些手套,然后选出一双颜色相同的左右手手套。现在的问题是,他至少要拿多少只手套(左手加右手),才能保证一定能选出一双颜色相同的手套。
给定颜色种数n(1≤n≤13),同时给定两个长度为n的数组left,right,分别代表每种颜色左右手手套的数量。数据保证左右的手套总数均不超过26,且一定存在至少一种合法方案。
测试样例:
4,[0,7,1,6],[1,5,0,6]
返回:10(解释:可以左手手套取2只,右手手套取8只)
简单分析:这道题我实在是想不透,不过看别人的大体思想还是写出了程序。
要找最少的手套个数,要分两种情况:
1、在左右手套每种颜色都不为0时,我们只需把左手手套每种颜色全部取到(左手手套总数-左手最小手套数+1),再取一个右手手套就一定可以匹配;然后把右手手套每种颜色全部取到(右手手套总数-右手最小手套数+1),再取一个左手手套就一定可以匹配,然后取两者最小值。
2、在左右手手套有某种颜色手套数量为0时,我们需要做如下考虑:
【0 7 1 6】 【1 5 0 6】,我们可以很容易看到。在把左右手为0的颜色排除考虑时,右手取7只就能把剩下的所以颜色取到,左手取1只就行。但是如果把为0的考虑进去,左手可能取第3种颜色进而无法匹配,所以左手要取1+1只手套;右手取7只手套可能正好把颜色1和4取到,没有达到取区别颜色的目的,所以需要额外多取几个以保证颜色1的手套不会影响我们取到全部颜色。
代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int findMinimum(int n, vector<int> left, vector<int> right)
{
// write code here
int left_min = INT_MAX, left_sum = 0;
int right_min = INT_MAX, right_sum = 0;
int sum = 0;
for (int i = 0; i < n; ++i)
{
if (left[i] * right[i] == 0)
sum += left[i] + right[i];
else
{
left_sum += left[i];
left_min = min(left_min, left[i]);
right_sum += right[i];
right_min = min(right_min, right[i]);
}
}
return sum + min(left_sum - left_min + 1, right_sum - right_min + 1) + 1;
}
int main()
{
vector<int> left = { 10, 9, 8, 7 };
vector<int> right = { 4, 3, 2, 1 };
int ret = findMinimum(4, left, right);
cout << ret << endl;
return 0;
}