题目描述
1153 Decode Registration Card of PAT (25分)
知识点
STL的使用,排序
实现
码前思考
- 大型模拟题
- 针对每一种情况,我都使用了一个容器存储结果,这样查询的时候就可以直接查询了。
//究极模拟题
//注意判空
#include "bits/stdc++.h"
using namespace std;
int n;
int m;
struct node{
string id;
int score;
node(){};
node(string _id,int _score):id(_id),score(_score){}
};
struct dot{
int site;
int number;
dot(){};
dot(int _site,int _number):site(_site),number(_number){}
};
unordered_map<char,int> c2n;
vector<node> level[3];
unordered_map<int,int> case21;
unordered_map<int,int> case22;
unordered_map<int,unordered_map<int,dot>> case3;
bool isSort[3];
bool cmp1(node a,node b){
return a.score == b.score ? a.id<b.id : a.score > b.score;
}
bool cmp2(dot a,dot b){
return a.number == b.number ? a.site < b.site : a.number > b.number;
}
int main(){
c2n['T'] = 0;
c2n['A'] = 1;
c2n['B'] = 2;
fill(isSort,isSort+3,false);
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++){
string id;
int score;
cin>>id>>score;
//首先是将其加入到某个考场中
int l = c2n[id[0]];
level[l].push_back(node(id,score));
//然后是统计考点的分数和人数
int site = stoi(id.substr(1,3));
case21[site] += 1;
case22[site] += score;
//然后是统计某个时间某个考场的人
int time = stoi(id.substr(4,6));
//查看是否已经有这个考点了
if(case3[time].count(site) == 0){
case3[time][site] = dot(site,1);
}else{
case3[time][site].number++;
}
}
//下面是进行查询
for(int i=0;i<m;i++){
int type;
scanf("%d",&type);
if(type == 1){
char c;
//注意空格?
scanf(" %c",&c);
int l = c2n[c];
printf("Case %d: %d %c\n",i+1,type,c);
//输出这一个等级的所有成绩
if(level[l].size()==0){
printf("NA\n");
}else{
if(isSort[l] == false){
sort(level[l].begin(),level[l].end(),cmp1);
isSort[l] = true;
}
for(int j=0;j<level[l].size();j++){
cout<<level[l][j].id<<" "<<level[l][j].score<<endl;
}
}
}else if(type == 2){
int site;
scanf("%d",&site);
printf("Case %d: %d %d\n",i+1,type,site);
if(case21.count(site) == 0){
printf("NA\n");
}else{
printf("%d ",case21[site]);
printf("%d\n",case22[site]);
}
}else if(type == 3){
int date;
scanf("%d",&date);
//注意前导0
printf("Case %d: %d %06d\n",i+1,type,date);
if(case3.count(date) == 0){
printf("NA\n");
}else{
vector<dot> res;
for(auto it2=case3[date].begin();it2!=case3[date].end();it2++){
res.push_back(it2->second);
}
sort(res.begin(),res.end(),cmp2);
for(int j=0;j<res.size();j++){
printf("%d %d\n",res[j].site,res[j].number);
}
}
}
}
return 0;
}
码后反思
- 最后一个测试用例会超时,于是我对第一个测试用例加了一个判断,如果排序过了,下次就直接输出,然后就没超时了。。。
- 我看大神的代码简洁多了。。。如下:
大神居然是每次查询都遍历所有的数据,居然没超时,很奇怪。。。#include <iostream> #include <vector> #include <unordered_map> #include <algorithm> using namespace std; int N, M, choose; string tmp; pair<string, int> cards[11000]; bool cmp(pair<string, int> p1, pair<string, int> p2) { return p1.second != p2.second ? p1.second > p2.second : p1.first < p2.first; } int main() { cin >> N >> M; for(int i = 0; i < N; i++) cin >> cards[i].first >> cards[i].second; for(int c = 1; c <= M; c++) { cin >> choose >> tmp; printf("Case %d: %d %s\n", c, choose, tmp.c_str()); if(choose == 1) { vector<pair<string, int>> v; for(int i = 0; i < N; i++) if(cards[i].first[0] == tmp[0]) v.push_back(cards[i]); if(v.size() != 0) { sort(v.begin(), v.end(), cmp); for(auto x : v) printf("%s %d\n", x.first.c_str(), x.second); } else printf("NA\n"); } else if(choose == 2) { int cnt = 0, all_score = 0; for(int i = 0; i < N; i++) { if(cards[i].first.substr(1, 3) == tmp) { cnt++; all_score += cards[i].second; } } if(cnt != 0) printf("%d %d\n", cnt, all_score); else printf("NA\n"); }else { unordered_map<string, int> m; for(int i = 0; i < N; i++) if(cards[i].first.substr(4, 6) == tmp) m[cards[i].first.substr(1, 3)]++; if(m.size() != 0) { vector<pair<string, int>> v(m.begin(), m.end()); sort(v.begin(), v.end(), cmp); for(auto x: v) printf("%s %d\n", x.first.c_str(), x.second); } else printf("NA\n"); } } return 0; } // B 123 180908 127 // 1 decreasing // 2 Nt Ns // 3 Nnumber testee