PAT A1080(测试点4运行超时与段错误)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 40010;
int n, m, k;
struct School{
	int sid;
	int plan;//计划招收
	int acc;//实际招收 
	int cr;//当前考生排名 
	bool exceeded;//是否招满 
	int list[1010];
}rec_sch[110];
struct stu{
	int id;
	int Ge, Gi, Gf, rank;
	int aim[8];
}rec[N];
bool cmp(stu a, stu b)
{
	if(a.Gf != b.Gf) return a.Gf > b.Gf;
	else if(a.Ge != b.Ge) return a.Ge > b.Ge;
}
void init()
{
	for (int i = 0; i < m; i++){
		rec_sch[i].sid = i;
		rec_sch[i].acc = 0;
		rec_sch[i].exceeded = false;
	}
}

int main()
{
	scanf("%d%d%d",&n, &m, &k);	
	init();
	for(int i = 0; i < m; i++) scanf("%d", &rec_sch[i].plan);
	for(int i = 0; i < n; i++){
		rec[i].id = i; 
		scanf("%d%d", &rec[i].Ge, &rec[i].Gi);
		rec[i].Gf = (rec[i].Ge + rec[i].Gi) >> 1;///
		for (int j = 0; j < k; j++) scanf("%d", &rec[i].aim[j]);
	}
	sort(rec, rec + n, cmp);
	int r = 1;
	rec[0].rank = 1;
	for(int i = 1; i < n; i++){//排名 
		if(rec[i].Gf == rec[i - 1].Gf && rec[i].Ge == rec[i - 1].Ge){
			rec[i].rank = r;
		}else{
			rec[i].rank = i + 1;
			r = i + 1;
		}
	}

	for(int i = 0; i < n; i++){
		for (int j = 0; j < k; j++){
			int cur = rec[i].aim[j];//当前申请学校编号 
			if(!rec_sch[cur].exceeded){//学校未招满 
				rec_sch[cur].list[rec_sch[cur].acc] = rec[i].id;
				rec_sch[cur].acc++;
				rec_sch[cur].cr = rec[i].rank; 
				if(rec_sch[cur].acc >= rec_sch[cur].plan) rec_sch[cur].exceeded = true;
				break;//不再继续申请 
			}
			else if(rec[i].rank == rec_sch[cur].cr){
				rec_sch[cur].list[rec_sch[cur].acc] = rec[i].id;
				rec_sch[cur].acc++;
				break;//不再继续申请 
			}
		}
	}
	for(int i = 0; i < m; i++){
		sort(rec_sch[i].list, rec_sch[i].list + rec_sch[i].acc);
		if(rec_sch[i].acc == 0) printf("\n");
		else{
			printf("%d", rec_sch[i].list[0]);
			for (int j = 1; j < rec_sch[i].acc; j++) printf(" %d", rec_sch[i].list[j]);
			printf("\n");
		}
	}
	return 0;
}

👆测试点4运行超时,原因是重复的数组访问次数过多

解决方法是利用变量记录反复使用的数

据,避免不必要的数组访问

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 40010;
int n, m, k;
struct School{
	int sid;
	int plan;//计划招收
	int acc;//实际招收 
	int cr;//当前考生排名 
	int list[N];
}rec_sch[110];
struct stu{
	int id;
	int Ge, Gi, Gf, rank;
	int aim[7];
}rec[N];
bool cmp(stu a, stu b)
{
	if(a.Gf != b.Gf) return a.Gf > b.Gf;
	else if(a.Ge != b.Ge) return a.Ge > b.Ge;
}
void init()
{
	for (int i = 0; i < m; i++){
		rec_sch[i].sid = i;
		rec_sch[i].acc = 0;
		rec_sch[i].cr = -1;
	}
}

int main()
{
	scanf("%d%d%d",&n, &m, &k);	
	for(int i = 0; i < m; i++) scanf("%d", &rec_sch[i].plan);
	init();
	for(int i = 0; i < n; i++){
		rec[i].id = i; 
		scanf("%d%d", &rec[i].Ge, &rec[i].Gi);
		rec[i].Gf = (rec[i].Ge + rec[i].Gi) >> 1;///
		for (int j = 0; j < k; j++) scanf("%d", &rec[i].aim[j]);
	}
	sort(rec, rec + n, cmp);
	int r = 1;
	rec[0].rank = 1;
	for(int i = 1; i < n; i++){//排名 
		if(rec[i].Gf == rec[i - 1].Gf && rec[i].Ge == rec[i - 1].Ge){
			rec[i].rank = r;
		}else{
			rec[i].rank = i + 1;
			r = i + 1;
		}
	}

	for(int i = 0; i < n; i++){
		for (int j = 0; j < k; j++){
			int cur = rec[i].aim[j];//当前申请学校编号 
			int num = rec_sch[cur].acc;//当前招生数 
			int last = rec_sch[cur].cr;
			if(num < rec_sch[cur].plan || (rec[i].rank == last && last != -1)){//学校未招满 
				rec_sch[cur].list[num] = rec[i].id;
				rec_sch[cur].acc++;
				rec_sch[cur].cr = rec[i].rank; 
				break;//不再继续申请 
			}
		}
	}
	for(int i = 0; i < m; i++){
		sort(rec_sch[i].list, rec_sch[i].list + rec_sch[i].acc);
		if(rec_sch[i].acc == 0) printf("\n");
		else{
			printf("%d", rec_sch[i].list[0]);
			for (int j = 1; j < rec_sch[i].acc; j++) printf(" %d", rec_sch[i].list[j]);
			printf("\n");
		}
	}
	return 0;
}

 👆接下来出现测试点4的段错误

段错误:可能是数组越界,堆栈溢出(比如,递归调用层数太多)等情况引起

问题出在cmp函数

bool cmp(stu a, stu b)
{
	if(a.Gf != b.Gf) return a.Gf > b.Gf;
	else return a.Ge > b.Ge;
}

👆更改后ac

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值