PAT甲级 1012 The Best Rank
文章目录
做题整理
注意点
1 二维排序
sort()函数,默认的是对二维数组按照第一列进行排序
sort(viA.begin(), viA.end());//默认为从小到大排序
要从大到小排序: greater()
如果想用第二列或者第三列就必须通过重写第三参数的输入规则。这里有两种改写方式:
sort(viA.begin(), viA.end(), [](const vector<int> &a, const vector<int> &b) {return a[0] < b[0]; });
或者
bool cmp1(const vector<int> &a, const vector<int> &b)
{
return a[0] > b[0];
}
sort(viA.begin(), viA.end(), cmp1);
2 二维数组的创建
如果要用到sort()函数之类的STL模板,一定要用vector而不是[]。
数组创建如下:
vector<int> vec(4,2); //将含有4个数据的一维动态数组初始为2
vector< vector<int> > asd1(row, vector<int>(column, 0)); //初始化row*column二维动态数组,初始化值为0
3 index公共int报warning
warning: built-in function ‘index‘ declared as non-function
“内建函数index被声明为非函数”,也就是说index是一个内建函数,查了一下,这确实是个函数。因此,修改一下变量的名字,就不会报错了。
4 iterator迭代器的使用
vector容器的迭代器定义
std::vector<int> ::iterator it; //it能读写vector<int>的元素
std::vector<int>::const_iterator it;//it只能读vector<int>的元素,不可以修改vector<int>中的元素
map容器的迭代器定义
map<char,string>::iterator it; //it能读写map<char,string>的元素
map<char,string>::const_iterator it;//it只能读map<char,string>的元素,不可以修改map<char,string>中的元素
list容器的迭代器定义
list<int>::iterator it; //it能读写list<int>的元素
list<int>::const_iterator it;//it只能读list<int>的元素,不可以修改list<int>中的元素
vector迭代器定义时,前面必须使用命名空间std,否则会报错。而其他的容器(map、list)有没有命名空间std都不会报错。
5 Map添加数据
maplive.insert(pair<int,string>(102,"aclive"));
maplive.insert(map<int,string>::value_type(321,"hai"));
maplive[112]="April";//map中最简单最常用的插入添加!
6 Char转换为Str
const char c = 'a';
//1.使用 string 的构造函数
string s(1,c);
//2.声明string 后将char push_back
string s1;
s1.push_back(c);
//3.使用stringstream
stringstream ss;
ss << c;
string str2 = ss.str();
//注意 使用to_string 方法会转化为char对应的ascii码
//原因是 to_string 没有接受char型参数的函数原型,有一个参数类型
//为int 的函数原型,所以传入char型字符 实际是先将char 转化
//为int 型的ascii 码,然后再转变为string
//以下输出结果为 97
cout << to_string(c) << endl;
7 int 转换为 String
string to_string (int val);
原代码
#include<bits/stdc++.h>
using namespace std;
int pos;
bool cmpk(const vector<int> &a, const vector<int> &b) {
return a[pos] > b[pos];
}
int main() {
int N, M;
cin >> N >> M;
string id[N], searchid;
vector<vector<int>> grades(N, vector<int>(5, 0));
int rank[N][4];
map<string, string> ranklist;
string subjects[4] = {"A", "C", "M", "E"};
for(int i = 0 ; i < N; i++) {
cin >> id[i];
for(int k = 1; k < 4; k++)
cin >> grades[i][k];
grades[i][0] = grades[i][1] + grades[i][2] + grades[i][3];
grades[i][5] = i;
}
for(pos = 0 ; pos < 4; pos++) {
int realrank = 1;
sort(grades.begin(), grades.end(), cmpk);
rank[ grades[0][5] ][pos] = 1;
for(int i = 1; i < N; i++) {
if(grades[i][pos] != grades[i-1][pos])
realrank++;
rank[ grades[i][5] ][pos] = realrank;
}
}
for(int i = 0 ; i < N; i++) {
int tempsub = 0;
for(int j = 1 ; j < 4; j++) {
if(rank[i][j] < rank[i][tempsub])
tempsub = j;
}
string rankstr = to_string(rank[i][tempsub])+ " "+ subjects[tempsub];
ranklist.insert(pair<string, string>(id[i], rankstr));
}
for(int i = 0 ; i < M ; i++) {
cin >> searchid;
map<string, string>::iterator iter = ranklist.find(searchid);
if(iter != ranklist.end())
cout << iter->second;
else
cout << "N/A";
if(i < M-1)
cout << endl;
}
return 0 ;
}
运行结果
测试点2错误
查看了别人的代码,原来是果存在分数相同,那么排名也应该是相同的,比如 1 1 3 4 5
蛮无语的,可能个人理解不同,我自己觉得如果上面那个排名相同,结果应该是 1 1 2 3 4
只能说题意理解不同吧,也可能是我平时的认知和一般的不太一样?
新代码
#include<bits/stdc++.h>
using namespace std;
/* 1012 */
int pos; //比较A,C,M,E中的一项
bool cmpk(const vector<int> &a, const vector<int> &b) {
return a[pos] > b[pos];
}
int main() {
int N, M;
cin >> N >> M;
string id[N], searchid;
vector<vector<int>> grades(N, vector<int>(5, 0)); //定义N*5的二维数组,均初始化为0,0-4列分别为A,C,M,E成绩和原始输入序号i
int rank[N][4]; //存放每一学生每一项的排名
map<string, string> ranklist; //存放最后结果,map便于查询
string subjects[4] = {"A", "C", "M", "E"};
for(int i = 0 ; i < N; i++) {
cin >> id[i];
for(int k = 1; k < 4; k++)
cin >> grades[i][k];
grades[i][0] = grades[i][1] + grades[i][2] + grades[i][3]; //考虑到如果直接用题目的均值,会出现double进位后精度损失的问题,故直接用和,更准确
grades[i][5] = i; //初始化原有输入顺序,与id下标对应
}
for(pos = 0 ; pos < 4; pos++) {
sort(grades.begin(), grades.end(), cmpk); //对于A-E中的每一列进行排序
rank[ grades[0][5] ][pos] = 1;
for(int i = 1; i < N; i++) {
if(grades[i][pos] == grades[i-1][pos]) //如果和上一项分数相同,则排名一样
rank[ grades[i][5] ][pos] = rank[ grades[i-1][5] ][pos];
else //如果不相同,则采用原始输入顺序+1(+1是因为下标i从0开始)
rank[ grades[i][5] ][pos] = i+1;
}
}
for(int i = 0 ; i < N; i++) {
int tempsub = 0;
for(int j = 1 ; j < 4; j++) {
if(rank[i][j] < rank[i][tempsub]) //找出每个学生排名最高的项
tempsub = j;
}
string rankstr = to_string(rank[i][tempsub])+ " "+ subjects[tempsub];
ranklist.insert(pair<string, string>(id[i], rankstr));
}
for(int i = 0 ; i < M ; i++) {
cin >> searchid;
if(ranklist.count(searchid))
cout << ranklist[searchid]<<endl;
else
cout << "N/A" <<endl;
}
return 0 ;
}
运行结果
想法
看了别人的代码,很多是采用结构体实现的,确实应该如此,下次这类题型注意写成结构体的形式,不要偷懒。