7-5 點贊狂魔(25 分)
微博上有個“點贊”功能,你可以爲你喜歡的博文點個贊表示支持。每篇博文都有一些刻畫其特性的標籤,而你點讚的博文的類型,也間接刻畫了你的特性。然而有這麼一種人,他們會通過給自己看到的一切內容點贊來狂刷存在感,這種人就被稱爲“點贊狂魔”。他們點讚的標籤非常分散,無法體現出明顯的特性。本題就要求你寫個程序,通過統計每個人點讚的不同標籤的數量,找出前3名點贊狂魔。
輸入格式:
輸入在第一行給出一個正整數N(≤100),是待統計的用戶數。隨後N行,每行列出一位用戶的點贊標籤。格式爲“Name
K F1⋯FK”,其中Name
是不超過8個英文小寫字母的非空用戶名,1≤K≤1000,Fi(i=1,⋯,K)是特性標籤的編號,我們將所有特性標籤從1到107編號。數字間以空格分隔。
輸出格式:
統計每個人點讚的不同標籤的數量,找出數量最大的前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
這題的思路表達的有點模糊,我只想表示,真的好麻煩啊。
#include<stdio.h>
#include<string.h>
struct student{
char name[9];
int Num;
int Tag[1000];
int WorkNum;
double Average;
};
int main()
{
int i, j, n, T ,u;
double R;
char CH[15];
scanf("%d", &n);
struct student Student[n];
for( i=0; i<n; i++ ) {
scanf("%s", &Student[i].name);
scanf("%d", &Student[i].Num);
Student[i].WorkNum=0;
for( j=0; j<Student[i].Num; j++ )
scanf( "%d", &Student[i].Tag[j] );
}
for( i=0; i<n; i++ )
for( u=0; u<Student[i].Num-1; u++ )
for( j=u+1; j<Student[i].Num; j++ )
if(Student[i].Tag[u]==Student[i].Tag[j])
Student[i].Tag[j] = 0;
for( i=0; i<n; i++ ) {
for( j=0; j<Student[i].Num; j++ )
if(Student[i].Tag[j]!=0)
Student[i].WorkNum++;
Student[i].Average = (double)Student[i].Num/Student[i].WorkNum;
}
for( i=0; i<n-1; i++ )
for( j=i+1; j<n; j++ )
if( Student[i].WorkNum < Student[j].WorkNum ){
strcpy(CH, Student[i].name);
strcpy(Student[i].name, Student[j].name);
strcpy(Student[j].name, CH);
T = Student[i].WorkNum;
Student[i].WorkNum=Student[j].WorkNum;
Student[j].WorkNum=T;
R=Student[i].Average;
Student[i].Average=Student[j].Average;
Student[j].Average=R;
}
for( i=0; i<n; i++ )
for( j=i+1; j<n; j++ )
if( Student[i].WorkNum==Student[j].WorkNum&&Student[i].Average>Student[j].Average ){
strcpy(CH, Student[i].name);
strcpy(Student[i].name, Student[j].name);
strcpy(Student[j].name, CH);
R=Student[i].Average;
Student[i].Average=Student[j].Average;
Student[j].Average=R;
}
if( n>2 )
for( i=0; i<3; i++ ) {
printf("%s",Student[i].name);
if(i<2)
printf(" ");
if( !Student[i+1].name )
break;
}
if( i==1 )
printf("%s - -", Student[0].name);
if(i==2)
printf("%s %s -", Student[0].name, Student[1].name);
return 0;
}
第二個方法,我用數組做的,原理和結構一樣:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void Swap(int *a, int *b)
{
int t=*a; *a=*b; *b=t;
}
void Swapdouble(double *c, double *d)
{
double t=*c; *c=*d; *d=t;
}
int main()
{
int i, j, k, n, T;
scanf("%d", &n);
int Num[n], Tag[n][1000], Num1[n];
double R,Average[n];
char *name[200], CH[19];
for( i=0; i<n; i++ ) {
scanf("%s", CH);
name[i] = (char*)malloc(sizeof(char)*10);
strcpy( name[i], CH );
scanf("%d", &Num[i]);
Num1[i] = 0;
for( j=0; j<Num[i]; j++ )
scanf("%d", &Tag[i][j]);
}
for( i=0; i<n; i++ )
for( j=Num[i]-1; j>=0; j-- )
for( k=0; k>=0&&k<j; k++ )
if(Tag[i][j]==Tag[i][k])
Tag[i][j] = 0;
for( i=0; i<n; i++ )
for( j=0; j<Num[i]; j++ )
if( Tag[i][j]!=0 )
Num1[i]++;
for( i=0; i<n; i++ )
Average[i] = (double)Num[i]/Num1[i];
for( i=0; i<n-1; i++ )
for( j=i+1; j<n; j++ )
if( Num1[i]<Num1[j] ) {
Swap( &Num1[i], &Num1[j]);
Swapdouble(&Average[i], &Average[j]);
strcpy(CH, name[i]);
strcpy(name[i], name[j]);
strcpy(name[j], CH);
}
for( i=0; i<n-1; i++ )
for( j=i+1; j<n; j++ )
if( Num1[i]==Num1[j]&&Average[i]>Average[j]) {
strcpy(CH, name[i]);
strcpy(name[i], name[j]);
strcpy(name[j], CH);
Swapdouble(&Average[i], &Average[j]);
}
if( n>2 )
for( i=0; i<3; i++ ) {
printf("%s", name[i]);
if( i<2 ) printf(" ");
}
if( n==1 )
printf("%s - -", name[0]);
if( n==2 )
printf("%s %s-", name[0], name[1]);
return 0;
}