题目链接
限行-美团2023笔试(codefun2000)
题目内容
塔子哥是一个富有的商人,他在一家大型贸易公司工作。他的公司位于城市的中心区,是一座高耸的摩天大楼。他住在郊区的别墅,是一座豪华的欧式建筑。他每天都要开车上下班,穿越城市的繁华和拥堵。
不幸的是,这个城市为了缓解交通拥堵,实行了限行规则,每天都有一些车牌号的最后一位数字被禁止上路。
塔子哥不想因为限行而迟到或者请假,因为他的工作很重要,涉及到很多国际贸易的合同和谈判。所以他想买几辆车,让他每天都有车可以用。
假设他不能换车牌号,也不能选择其他交通方式,而且他的工作时间是固定的,问他至少需要买多少辆车?如果没有办法做到,就输出 −1 。
输入描述
输入一共有 7 行,表示周一至周日的限行情况。
输入每一行,第 i 行的第一个数字 ci表示当天限行数字个数,随后输入 ci个互不相同的数字,第 j 个数字为 aij ,表示限行数字。
对于所有的数据, 0≤ci ≤10,0≤aij≤9 。
输出描述
输出为一个整数,表示塔子哥需要的最少车辆数或塔子哥不能保证每天都至少有一辆车可以出行。
样例1
输入
8 0 1 2 3 4 5 6 7
8 1 2 3 4 5 6 7 8
8 2 3 4 5 6 7 8 9
8 0 1 2 3 4 5 8 9
8 0 1 2 3 6 7 8 9
8 0 1 4 5 6 7 8 9
8 2 3 4 5 6 7 8 9
输出
5
提示
一种可能的方案是,选购最后车牌一位数字分别为 0,2,4,6,8 的 5 辆车,此时每天都有车辆可以出行。
题解1
#include<bits/stdc++.h>
using namespace std;
set<int> st[10];
int c, a[20];
bool vis[20];
int main(){
int ans = 10;
for(int i = 1; i <= 7; i++){
scanf("%d", &c);
memset(vis, 0, sizeof vis);
for(int j = 1; j <= c; j++){
scanf("%d", &a[j]);
vis[a[j]] = 1;
}
for(int j = 0; j <= 9; j++){
if(!vis[j]) st[j].insert(i); // 选择车牌号为j的车,可以在第i天通行
}
}
for(int i = 1; i <= (1<<9); i++){ // 二进制枚举所有的可能性
set<int> s;
int cnt = 0; // 当前方案下,需要的最少车辆数
for(int j = 9; j >= 0; j--){
if(i&(1<<j)){
for(auto k : st[j]) s.insert(k);
cnt++;
}
}
if(s.size() == 7) ans = min(ans, cnt); // 保证每天都至少有一辆车可以出行
}
printf("%d\n", ans == 10 ? -1 : ans);
return 0;
}