vector<node> Node(N)存储数据,用一个map记录了出现过的学校记录在Node的第几个
我是自己写的转换小写函数,用<cctype>中的tolower()更方便,我写的时候忘了
有个很有趣的问题,我一开始没有使用ans,直接对Node进行了排序(很可能有空结点),然后取前map.size()个结点输出,我一开始觉得逻辑没有问题,空结点会排在后面。然后发现第五个测试点过不去,然后我查了大家对第五个测试点的说明,都说是TWS的计算转化顺序问题,我仔细看来看去没发现我在这点上有不对,想了很久
后来试来试去,使用了ans来存储出现过的学校结点(即没有空结点参与排序),然后发现就AC了,这时候我才意识到,测试点5里的数据,应该有成绩为0的学校,所以在空结点参与排序时,根据cmp的排序顺序,string为空的会<string有字母的,所以空结点会排在0分学校之前。想到之后又好气又好笑,还能有0分的学校,一时有点语塞。
所以总结补充一下测试点5的可能错误:
1、TWS计算顺序问题,应该每个点都加在double型总和里,最后再强制转化为int
2、如果你和我一样的思路让空结点参与了排序,小心TWS数据为0的结点,会被排在空结点之后
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
int N;
struct node{
string name;
double TWS=0;
int Ns=0;
int rank;
};
unordered_map<string,int> scl_tag;
string lowercase(string x){
string lower;
for(int i=0;i<x.length();i++){
if(x[i]-'A'>=0&x[i]-'Z'<=0){
lower+=x[i]+32;
}else{
lower+=x[i];
}
}
return lower;
}
bool cmp(const node a,const node b){
if((int)a.TWS==(int)b.TWS){
if(a.Ns==b.Ns){
return a.name<b.name;
}else{
return a.Ns<b.Ns;
}
}else{
return (int)a.TWS>(int)b.TWS;
}
}
int main(){
cin>>N;
vector<node> Node(N);
vector<node> ans;
for(int i=0;i<N;i++){
string id,school;
double score;
cin>>id>>score>>school;
school=lowercase(school);
if(scl_tag.find(school)==scl_tag.end()){
scl_tag[school]=i;
Node[i].name=school;
}
int tag=scl_tag[school];
Node[tag].Ns++;
if(id[0]=='B'){
Node[tag].TWS+=(score/1.5);
}else if(id[0]=='A'){
Node[tag].TWS+=score;
}else{
Node[tag].TWS+=(score*1.5);
}
}
for(auto it:scl_tag){
ans.push_back(Node[it.second]);
}
sort(ans.begin(),ans.end(),cmp);
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++){
if(i==0){
ans[i].rank=i+1;
cout<<ans[i].rank<<" "<<ans[i].name<<" "<<(int)ans[i].TWS<<" "<<ans[i].Ns<<endl;
}else{
if((int)ans[i].TWS==(int)ans[i-1].TWS){
ans[i].rank=ans[i-1].rank;
}else{
ans[i].rank=i+1;
}
cout<<ans[i].rank<<" "<<ans[i].name<<" "<<(int)ans[i].TWS<<" "<<ans[i].Ns<<endl;
}
}
return 0;
}
再附上我一开始的错误代码,对比一下引以为鉴:
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
int N;
struct node{
string name;
double TWS=0;
int Ns=0;
int rank;
};
unordered_map<string,int> scl_tag;
string lowercase(string x){
string lower;
for(int i=0;i<x.length();i++){
if(x[i]-'A'>=0&x[i]-'Z'<=0){
lower+=x[i]+32;
}else{
lower+=x[i];
}
}
return lower;
}
bool cmp(const node a,const node b){
if((int)a.TWS==(int)b.TWS){
if(a.Ns==b.Ns){
return a.name<b.name;
}else{
return a.Ns<b.Ns;
}
}else{
return (int)a.TWS>(int)b.TWS;
}
}
int main(){
cin>>N;
vector<node> Node(N);
for(int i=0;i<N;i++){
string id,school;
double score;
cin>>id>>score>>school;
school=lowercase(school);
if(scl_tag.find(school)==scl_tag.end()){
scl_tag[school]=i;
Node[i].name=school;
}
int tag=scl_tag[school];
Node[tag].Ns++;
if(id[0]=='B'){
Node[tag].TWS+=(score/1.5);
}else if(id[0]=='A'){
Node[tag].TWS+=score;
}else{
Node[tag].TWS+=(score*1.5);
}
}
sort(Node.begin(),Node.end(),cmp); //差别主要在这里之后
printf("%d\n",scl_tag.size());
for(int i=0;i<scl_tag.size();i++){
if(i==0){
Node[i].rank=i+1;
cout<<Node[i].rank<<" "<<Node[i].name<<" "<<(int)Node[i].TWS<<" "<<Node[i].Ns<<endl;
}else{
if((int)Node[i].TWS==(int)Node[i-1].TWS){
Node[i].rank=Node[i-1].rank;
}else{
Node[i].rank=i+1;
}
cout<<Node[i].rank<<" "<<Node[i].name<<" "<<(int)Node[i].TWS<<" "<<Node[i].Ns<<endl;
}
}
return 0;
}