题意
有多组数据,每一组以 e
开头,每一组给定当前城市的垃圾分配方式,让我们输出哪个城市应该评为“模范城市”,所有的输入以 #
结束。
所谓“模范城市”,即:
就是将这座城市的分配方式应用于其他所有城市,使得其他城市分配方式的改变最少。
分析
既然是每个颜色的垃圾桶有不同的垃圾,那么我们自然而然地想到字符串映射。
在输入分配方式的时候,将每个城市每个颜色的垃圾桶分配的垃圾记录下来。然后在新的一组开始时,双重循环所有城市,找到两个城市的颜色垃圾桶分配的垃圾,不同的话就记录个数,然后求出最小的一个修改值,并记录最小修改值的城市,并输出即可。
这里需要用到双重循环,但是数据范围表明所有城市个数 ≤ 100 \le 100 ≤100,最大的循环量也就 10000 10000 10000,是比较小的,双重循环城市个数是完全没问题的。
Code
// UVA154.Recycling
#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 105
using namespace std;
string str;
// 使用 map 字符映射
map <char, char> Mp[N];
int len, ans, sum, city, min1;
// 颜色数组
char color[10] = {'r', 'o', 'y', 'g', 'b'};
int main() {
while (1) {
cin >> str;
// 读取到 '#',输入结束
if (str[0] == '#') break;
// 读取到 'e',新的一组
if (str[0] == 'e') {
// 变量初始化
ans = 1;
sum = 0;
min1 = 0x3f3f3f3f;
// 循环当前城市个数
for (int i = 1; i <= city; i++) {
// 累加器清零
sum = 0;
for (int j = 1; j <= city; j++) {
// 如果两个城市相同,跳过
if (i == j) continue;
// 循环五个颜色
for (int k = 0; k < 5; k++) {
// 判断当前城市的颜色垃圾桶所放的垃圾是否相同
if (Mp[i][color[k]] != Mp[j][color[k]]) sum++;
}
}
// 取最小值
if (min1 > sum) {
ans = i;
min1 = sum;
}
}
// 输出答案
printf ("%d\n", ans);
// 城市计数器清零
city = 0;
continue;
}
// 不是新的一组,而是当前这一组接下来的数据
// 城市个数加一
city++;
len = str.size();
// 循环字符串
for (int i = 0; i < len; i++) {
// 找到 '/' 分界点,记录当前城市的颜色垃圾桶所放的垃圾
if (str[i] == '/') Mp[city][str[i - 1]] = str[i + 1];
}
}
return 0;
}
完结撒花。