個人對該問題寫的帖子地址:https://blog.csdn.net/Xavier_97/article/details/105889346
找遍了全網關于該題目相關的解釋和說明,也測驗了不少其他的用例,其他人反應的那些坑也都跳過去了,但是就是最后一個測驗點過不了。修改了自己的read函式,也修改過排序函式,均沒有通過,希望有做過這道題的同學能給點幫助謝謝,或者給出有問題的測驗用例,非常感謝!
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define MaxUsers 10001
typedef struct Stu{
int id;
int total;
int score[5];
int full;
} List[MaxUsers];
int read( int table[], List stu, int full_score[], int p_num, int m );
void Shell_Sort( int table[], List stu, int n);
int Check( int table[], List stu, int tmp, int tmpid, int j, int d );
void Init( List stu, int id, int p_num );
//int compare( const void *a, const void *b );
int main()
{
int n, k, m, i, j, real_user;
List stu;
scanf("%d %d %d", &n, &k, &m);
int full_score[k]; //記錄題目滿分
for ( i=0; i<k; ++i )
scanf("%d", &full_score[i]);
int table[n]; //table記錄需要顯示的用戶數,后面排序只需對table進行排序即可
for ( i=0; i<n; ++i )
table[i] = -1;
//開始讀資料,讀完回傳需要顯示的用戶數
real_user = read(table, stu, full_score, k, m);
// qsort(table, real_user, sizeof(int), compare); //對table進行快速排序
Shell_Sort(table, stu, real_user); //對table進行希爾排序
//以下按序輸出table中的用戶
int last;
for ( i=0; i<real_user; ++i )
{
int tmp = table[i];
if ( i == 0 )
{
printf("%d ", i+1);
last = i+1;
}
else{
if ( stu[tmp].total == stu[table[i-1]].total )
printf("%d ", last);
else{
printf("%d ", i+1);
last = i+1;
}
}
printf("%05d %d", tmp, stu[tmp].total);
for ( j=0; j<k; ++j )
{
if ( stu[tmp].score[j] != -1 )
printf(" %d", stu[tmp].score[j]);
else
printf(" -");
}
if ( i!=real_user-1 )
printf("\n");
}
return 0;
}
void Shell_Sort( int table[], List stu, int n)
{
int i, j, d, k = 0;
int tmp, tmpno;
while (pow(2, k)-1<n)
++k;
--k; //使用Hibbard增量序列
for( ; k>=1; --k )
{
d = pow(2,k)-1;
for ( i=d; i<n; ++i )
{
tmp = stu[table[i]].total; //tmp記錄當前用戶的總分
tmpid = table[i]; //tmpid記錄當前用戶的id
for ( j=i; j>=d && Check(table, stu, tmp, tmpid, j, d); j-=d )
{
table[j] = table[j-d];
}
table[j] = tmpno;
}
}
}
int Check( int table[], List stu, int tmp, int tmpid, int j, int d )
{
if ( tmp > stu[table[j-d]].total ) //總分比較
return 1;
else if ( tmp == stu[table[j-d]].total )
{
if ( stu[table[j]].full > stu[table[j-d]].full ) //滿分科目比較
return 1;
else if ( stu[table[j]].full == stu[table[j-d]].full )
{
if ( tmpid < table[j-d] ) //id大小比較
return 1;
}
}
return 0;
}
void Init( List stu, int id, int p_num ) //初始化當前序號的stu結構
{
int i;
stu[id].total = 0;
stu[id].full = 0;
for ( i=0; i<p_num; ++i )
stu[id].score[i] = -1;
}
int read( int table[], List stu, int full_score[], int p_num, int m )
{
int id, no, score, flag; //cnt用來記錄table陣列的移動,用于回傳需要顯示的用戶數
int i, j, k, cnt = -1; //record陣列記錄當前用戶狀態
int record[10001]; //record[id] == 0說明當前用戶并未有過任何操作
for ( i=0; i<10001; ++i) //record[id] == 1說明當前用戶已經滿足顯示排名的條件
record[i] = 0; //record[id] == 2說明當前用戶有過編譯記錄但是均未通過
for ( i=0; i<m; ++i )
{
scanf("%d %d %d", &id, &no, &score);
if ( !record[id] ) //如果該用戶從未編譯過
{
Init(stu, id, p_num); //初始化該用戶的結構,其中每題分數均記錄為-1
if ( score == -1 ){ //如果編譯失敗
stu[id].score[no-1] = -2; //將該門分數記錄為-2以便后續處理
record[id] = 2; //更改狀態為有過編譯記錄但是均未通過
}
else{ //如果編譯成功
stu[id].total = score; //總分更改
stu[id].score[no-1] = score; //該門分數值更改
if ( full_score[no-1] == score )//若滿分則滿分數加一
++stu[id].full;
table[++cnt] = id; //需要顯示的用戶數加一
record[id] = 1; //更改狀態為需要顯示
}
}
else if ( record[id] == 1 ) { //如果該用戶狀態為已經記錄為需要顯示的
if ( score == -1 ) //如果此次編譯失敗,將分數記為0
++score;
if ( score > stu[id].score[no-1] ) //如果這次分數大于上次的分數
{
if ( stu[id].score[no-1] == -1 )//若該題從未編譯過,直接將分數改為0
stu[id].score[no-1] = 0;
stu[id].total += (score-stu[id].score[no-1]);//總分加等于這次提交分數減掉原來分數
stu[id].score[no-1] = score; //該題成績更改
if ( full_score[no-1] == score )//若滿分則滿分數加一
++stu[id].full;
}
}
else if ( record[id] == 2 ) { //若該用戶狀態為提交過編譯但均失敗
if ( score == -1 ) //如果這次提交也編譯失敗
{
stu[id].score[no-1] = -2; //則本次提交打上編譯失敗的標記
}
else { //如果這次提交成功了(編譯通過)
for ( k=0; k<p_num; ++k ) //將之前所有被打上編譯失敗的題目均置為0分
if ( stu[id].score[k] == -2 )
stu[id].score[k] == 0;
table[++cnt] = id; //在table表上記錄該用戶
record[id] = 1; //該用戶狀態置為需要顯示的
stu[id].total = score; //總分置為此次提交的分數
stu[id].score[no-1] = score; //該題分數更新
}
}
}
return cnt+1; //回傳table中記錄的用戶數,即最終顯示的用戶數
}
uj5u.com熱心網友回復:
提示已經很清楚“最大化隨機測驗,重復提交滿分題目”。因為你代碼以stu.full作為排序比較,由于滿分則增加stu.full,看提示后半句去輸入資料,則導致排序不正確。
uj5u.com熱心網友回復:
感謝回答!但是我的代碼中確實加入了這個判斷, 如果重復提交滿分的話,那么這次分數不會大于上次的分數,也就不會做stu.full自增的操作,所以我感覺不是這里出了問題。if ( score > stu[id].score[no-1] ) //如果這次分數大于上次的分數
{
if ( stu[id].score[no-1] == -1 )//若該題從未編譯過,直接將分數改為0
stu[id].score[no-1] = 0;
stu[id].total += (score-stu[id].score[no-1]);//總分加等于這次提交分數減掉原來分數
stu[id].score[no-1] = score; //該題成績更改
if ( full_score[no-1] == score )//若滿分則滿分數加一
++stu[id].full;
uj5u.com熱心網友回復:
if(....==2)的分支里沒有滿分的判斷,stu.full沒有增加。uj5u.com熱心網友回復:
感謝提醒,這里確實沒有注意到。但是更改了之后最后一個測驗點還是未通過
else if ( record[id] == 2 ) { //若該用戶狀態為提交過編譯但均失敗
if ( score == -1 ) //如果這次提交也編譯失敗
{
stu[id].score[no-1] = -2; //則本次提交打上編譯失敗的標記
}
else { //如果這次提交成功了(編譯通過)
for ( k=0; k<p_num; ++k ) //將之前所有被打上編譯失敗的題目均置為0分
if ( stu[id].score[k] == -2 )
stu[id].score[k] == 0;
table[++cnt] = id; //在table表上記錄該用戶
record[id] = 1; //該用戶狀態置為需要顯示的
if ( full_score[no-1] == score )//若滿分則滿分數加一
++stu[id].full;
stu[id].total = score; //總分置為此次提交的分數
stu[id].score[no-1] = score; //該題分數更新
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/71317.html
標籤:C語言
上一篇:matlab 運行出錯 錯誤使用 * 內部矩陣維度必須一致。
下一篇:C語言佇列題目
