Judge最后一个测试点死活都不过去 PAT 1075 PAT

找遍了全网关于该题目相关的解释和说明,也测试了不少其他的用例,其他人反应的那些坑也都跳过去了,但是就是最后一个测试点过不了。修改了自己的read函数,也修改过排序函数,均没有通过,希望有做过这道题的同学能给点帮助谢谢,或者给出有问题的测试用例,非常感谢!
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181


#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中记录的用户数,即最终显示的用户数

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值