Time Limit: 20 second
Memory Limit: 20 MB
问题描述:
竞选时,要求选民在a,b,c,d四个候选人中选择(人数不限),如果选择了这四个人以外的人员,视为废票。统计时输入“*”结束,请按候选人得票数从大到小顺序输出候选人和其票数。0票也输出。
Input
输入在同一行
输入字符串以"*"结束
Output
输出统计的候选人姓名及其票数,统计结果按候选人得票数从大到小顺序输出。(若票数相同先出现字母的先输出)
Sample Input
输入:aadadadbdbbcd*
Sample Output
输出:d:5 a:4 b:3 c:1 回车
【题解】
以字符串输入数据,遇到什么字母相应的a[1..4]++就好。但输出的时候票数相同先出现的先输出,没有想到更好的解决办法,就用一个bo数组记录每个字符出现的先后顺序,如果遇到有相同票数的,按照bo数组再重新进行一次排序就好,只要处理相同数字的区间即可。
【代码】
#include <cstdio> #include <iostream> #include <string> const int maxl = 4; using namespace std; int a[maxl+1],number = 0; char b[maxl+1]; int bo[maxl+1]; string s1; void input_data() { for (int i = 1;i <= 4;i++) bo[i] = false;//先初始化 每个数字出现的时间为0 b[1] = 'a'; //设置一下每个数字对应的字母 b[2] = 'b'; b[3] = 'c'; b[4] = 'd'; cin >> s1;//把字符串输入 } void get_ans() { int i = 0; while (s1[i] != '*') //如果还没扫描到结束符号 { if (s1[i] == 'a') { a[1]++;//这是a ,对应1 票数递增 if (!bo[1]) bo[1] = ++number; //记录出现的先后顺序 } if (s1[i] == 'b') { a[2]++; if (!bo[2]) bo[2] = ++number; } if (s1[i] == 'c') { a[3]++; if (!bo[3]) bo[3] = ++number; } if (s1[i] == 'd') { a[4]++; if (!bo[4]) bo[4] = ++number; } i++; } bool flag = false; while (!flag) //先对票数进行排序 连同代表的字母和出现的先后顺序都要排序 { flag = true; for (int i = 1;i <= 3;i++) if (a[i] < a[i+1]) { int t = a[i];a[i] = a[i+1];a[i+1] = t; char te = b[i];b[i] = b[i+1];b[i+1] = te; t = bo[i];bo[i] = bo[i+1];bo[i+1] = t; flag = false; } } } void deal_ans(int l,int r) { bool flag = false; while (!flag) { flag = true; for (int i = l;i<=r-1;i++) if (bo[i] > bo[i+1]) { int t = a[i];a[i] = a[i+1];a[i+1] = t; char te = b[i];b[i] = b[i+1];b[i+1] = te; t = bo[i];bo[i] = bo[i+1];bo[i+1] = t; flag = false; } } } void output_ans() { for (int i = 1;i <= 4;i++) if (!bo[i]) bo[i] = ++number; int i = 1; while (i <= 4) //接下来处理票数相同的情况。 { int j = i + 1; while (j <= 4 && a[j] == a[i]) j++; deal_ans(i,j-1);//只要处理这个区间的数据就行,根据bo数组来处理 i = j; } for (int i = 1;i <= 4;i++) cout << b[i] << ':' << a[i] << endl; } int main() { //freopen("E:\rush.txt","r",stdin); input_data(); get_ans(); output_ans(); return 0; }