点赞狂魔
微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持。每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性。然而有这么一种人,他们会通过给自己看到的一切内容点赞来狂刷存在感,这种人就被称为“点赞狂魔”。他们点赞的标签非常分散,无法体现出明显的特性。本题就要求你写个程序,通过统计每个人点赞的不同标签的数量,找出前3名点赞狂魔。
输入格式:
输入在第一行给出一个正整数N(≤100),是待统计的用户数。随后N行,每行列出一位用户的点赞标签。格式为“Name K F1⋯FK”,其中Name是不超过8个英文小写字母的非空用户名,1≤K≤1000,Fi(i=1,⋯,K)是特性标签的编号,我们将所有特性标签从1到10^7编号。数字间以空格分隔。
输出格式:
统计每个人点赞的不同标签的数量,找出数量最大的前3名,在一行中顺序输出他们的用户名,其间以1个空格分隔,且行末不得有多余空格。如果有并列,则输出标签出现次数平均值最小的那个,题目保证这样的用户没有并列。若不足3人,则用-补齐缺失,例如mike jenny -就表示只有2人。
输入样例:
5
bob 11 101 102 103 104 105 106 107 108 108 107 107
peter 8 1 2 3 4 3 2 5 1
chris 12 1 2 3 4 5 6 7 8 9 1 2 3
john 10 8 7 6 5 4 3 2 1 7 5
jack 9 6 7 8 9 10 11 12 13 14
输出样例:
jack chris john
算法思路:
这题的规模其实并不是特别大,可以把所以用户的信息录入进去,再进行排序。但是我这里的做法就没那么粗暴,我先是定义一个用于储存3个点赞狂魔的结构体数组。然后还有一个结构体用于储存狂魔那个结构体数组里点赞数量最小的用户。每次的输入都和这个最小的用户比较,如果比这个最小用户点赞的数量要大,就把这个大的放到这个比他小的用户的位置。然后再从这三个位置找到用户点赞数量最小的,然后储存到最小点赞数的结构体里。重复以上过程,直到所有的用户录入完毕。最后对着个数组排序,就可以输出了。关于那句“标签出现次数平均值最小”,只的意思大概是:真实点赞的个数 / 点赞标签的种类数。
Code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Node { //点赞狂魔结构体
char Name[10];
int sum;
double a;
};
struct Min { //最小点赞数用户
int min;
int top;
double a;
}m;
int cmp( const void *a ,const void *b)
{
if (((*(struct Node *)a).sum < (*(struct Node *)b).sum) ||
((*(struct Node *)a).sum == (*(struct Node *)b).sum) &&
((*(struct Node *)a).a > (*(struct Node *)b).a)) {
return 1;
}
else {
return -1;
}
}
int main()
{
int i, N, x, cnt = 0, min = 0;
int K[1001];
scanf("%d", &N);
struct Node p, s[3];
m.min = -1;
m.top = 0;
for(i = 0; i < 3; i ++) {
s[i].sum = 0;
s[i].a = 0;
}
for(i = 0; i < N; i ++) {
scanf("%s", p.Name);
p.sum = 0;
int n;
scanf("%d", &n);
p.a = n; //真实点赞数
while(n --){
scanf("%d", &x);
int j, flag = 1;
for(j = 0; j <= p.sum; j ++) {
if(K[j] == x) {
flag = 0;
break;
}
}
if(flag) {
p.sum ++; //标签种类数
K[p.sum] = x;
}
}
p.a /= (p.sum * 1.0);
if(p.sum > m.min) { //判断当前输入的用户是否大于最小用户
int k;
/*将当前用户替换掉数组中最小用户*/
strcpy(s[m.top].Name, p.Name);
s[m.top].sum = p.sum;
s[m.top].a = p.a;
m.min = 1000;
for(k = 0; k < 3; k ++) { //找到更换后数组中的最小用户
if(m.min >= s[k].sum) {
if(m.min == s[k].sum) {
if(m.a > s[k].a) {
continue;
}
}
/*替换最小用户*/
m.min = s[k].sum;
m.top = k;
m.a = s[k].a;
}
}
}
}
qsort(s, 3, sizeof(s[0]), cmp); //调用快排函数
/*输出比较粗暴*/
if(N == 1) {
printf("%s - -", s[0].Name);
}
else if(N == 2) {
printf("%s %s -", s[0].Name, s[1].Name);
}
else {
printf("%s %s %s", s[0].Name, s[1].Name, s[2].Name);
}
return 0;
}
如果对C语言的快排函数不熟悉的,可以点击以下链接:
qsort()函数基本使用方法