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;
}