PAT 甲级 1153 Decode Registration Card of PAT (25分)

题目地址

Decode Registration Card of PAT (25分)

题目大意

这是一道模拟数据库查询的题目,样例给出了由考号和分数组成的数据信息。然后告诉了考号是由一位考试等级,三位考场编号、六位考试日期和三位考生号组成。我们需要实现三种查询数据的要求:

  • 查询类型1:根据考试等级查询,输出查询的考试等级的所有考生信息,输出形式是考号 成绩,并按照成绩降序排列,当成绩相同时,按照考号字符串大小升序排列,考号唯一。
  • 查询类型2:根据考场查找,输出查找考场的考生人数以及他们的总分数。
  • 查找类型3:根据考试日期查找,输出对应日期的考场号以及每个考场的人数,数据按照人数降序排列,当考场人数相同时按照考场号升序排列,考场号唯一。

解题思路

题目看似难度不大,但在解题中不注意细节很容易算法超时,或者陷入某些测试点错误需要花大量时间排查。

  • 如果使用串操作,输入输出方式频繁采用cin和cout,在检索时也用串进行比较很容易超时(最后2个测试点)。可以将考号划分后转为int和char类型存放,比较和输出会节约很多的时间。
  • 如果采用串输入输出不需要头部补0,如果用int型注意格式!
  • 查询类型1用sort排序就可以解决;查询类型2定义求和变量,求和筛选后的数据也容易得到结果。主要是查询类型3的设计方式会影响运行时间。
  • 查询类型3我用的是hash加上一个vector,时间复杂度和类型2差不多。我一开始采用vector,outnode{int sizeid,int sum}的存储模式需要在进行一次循环查找,就超时啦。真的可以用hash还是用hash比较好,空间基本不会超的。

测试点排查

前3个测试点包含的数据量比较小不会超时,后2个测试点会出现超时的情况,具体每个测试点包含的范围:

  • 每个测试点都包含查询类型1
  • 测试点0 就是样例给出的
  • 测试点2 只包含查询类型1
  • 测试点3 主要考察查询类型 3在数据量较大时是否超时,并且测试点3不包含查询类型2
  • 测试点4 考察查询类型1在数据量较大是否超时,包含部分查询类型2和查询类型3

完整代码

// A1153.cpp : Defines the entry point for the console application.
//

#include "stdio.h"
#include "string"
#include "vector"
#include "iostream"
#include "algorithm"
using namespace std;

struct node{
	string all;
	char first;
	int second,third,score;
};
int n,k;
vector<node> haha;
vector<node> da;
int hsh[11100];
vector<int> ans;

void add(string a,int x){
	node p;
	p.score = x;
	p.all = a;
	p.first = a[0];
	p.second = (a[1]-'0')*100+(a[2]-'0')*10+(a[3]-'0');
	p.third = (a[4]-'0')*100000+(a[5]-'0')*10000+(a[6]-'0')*1000+(a[7]-'0')*100+(a[8]-'0')*10+a[9]-'0';
	//p.f = (a[10]-'0')*100+(a[11]-'0')*10+a[12]-'0';
	//cout<<p.first<<p.second<<p.third<<p.f<<endl;
	haha.push_back(p);
}

bool cmp(node a,node b){
    if(a.score == b.score) return a.all < b.all;
	return a.score > b.score;
}

bool cmp1(int a,int b){
	if(hsh[a] == hsh[b]) return a < b;
	return hsh[a] > hsh[b];
}

void print(int typ){
	int i,sum = 0;
	if(typ == 2){
		for(i = 0;i < da.size();i++)
			sum += da[i].score;
		printf("%d %d\n",da.size(),sum);
	}
    if(typ == 3){
        ans.clear();
		fill(hsh,hsh+11100,0);
		for(i = 0;i < da.size();i++){
			if(hsh[da[i].second] == 0) ans.push_back(da[i].second);
			hsh[da[i].second] += 1;
		}
		sort(ans.begin(),ans.end(),cmp1);
		for(i = 0;i < ans.size();i++)
			printf("%03d %d\n",ans[i],hsh[ans[i]]);
	}
}

int main(int argc, char* argv[])
{
	int i = 1,flag = 0;
	scanf("%d %d",&n,&k);
	while(n--){
		int u;
		string t;
		cin>>t>>u;
		add(t,u);
	}
	sort(haha.begin(),haha.end(),cmp);
	while(i <= k){
        flag = 0;
		da.clear();
		int u,t,v;//u = 1 考级,= 2考场, = 3 日期
		char z = 0;
		scanf("%d",&u);
		printf("Case %d: ",i);
		if(u == 1){
            while(z != 'A' && z != 'T' && z!= 'B')
    			scanf("%c",&z);
			printf("%d %c\n",u,z);
		}else{
			scanf("%d",&v);
            if(u == 3)
                printf("%d %06d\n",u,v);
            else
    			printf("%d %03d\n",u,v);
		}
		for(t =0;t < haha.size();t++){
			node p = haha[t];
            if(u == 1){
                if(p.all[0] == z){
					cout<<p.all;
					printf(" %d\n",p.score);
                    flag = 1;
				}
            }else if(u == 2){
                if(p.second == v) da.push_back(p);
            }else{
                if(p.third == v) da.push_back(p);
            }
		}
		if(da.size() > 0){
			print(u);
		}else if(flag != 1){
			printf("NA\n");
		}
		i++;
	}
	//printf("Hello World!\n");
	return 0;
}

总结

用STL和sort就可以解决,难度一般主要是一些细节问题,相对板子题稍难,需要注意输入输出格式。

  • 欢迎评论区交流讨论。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值