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

Xaiver_97 2020-05-02 01:42:33
个人对该问题写的帖子地址: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中记录的用户数,即最终显示的用户数
}
...全文
374 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Xaiver_97 2020-05-03
  • 打赏
  • 举报
回复
感谢提醒,这里确实没有注意到。但是更改了之后最后一个测试点还是未通过

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;	//该题分数更新 
			}
		}
遇见女神 2020-05-02
  • 打赏
  • 举报
回复
引用 3 楼 Xavier_97 的回复:
感谢回答!但是我的代码中确实加入了这个判断, 如果重复提交满分的话,那么这次分数不会大于上次的分数,也就不会做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;
if(....==2)的分支里没有满分的判断,stu.full没有增加。
Xaiver_97 2020-05-02
  • 打赏
  • 举报
回复
感谢回答!但是我的代码中确实加入了这个判断, 如果重复提交满分的话,那么这次分数不会大于上次的分数,也就不会做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;
遇见女神 2020-05-02
  • 打赏
  • 举报
回复
提示已经很清楚“最大化随机测试,重复提交满分题目”。 因为你代码以stu.full作为排序比较,由于满分则增加stu.full,看提示后半句去输入数据,则导致排序不正确。

69,565

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧