需二刷
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
struct node{
int index,index0,wei;
int rank;
};
bool cmp(node &a,node&b){
return a.index0<b.index0;//都写成a细节错误精力不集中,最后要检查(注意)
}
int main(){
int n,k;
cin>>n>>k;
vector<int> wv(n);
vector<node> vv(n);
for(int i=0;i<n;i++){
scanf("%d",&wv[i]);
}
for(int i=0;i<n;i++){
int num;
cin>>num;
vv[i].index=i;
vv[i].index0=num;
vv[i].wei=wv[num];
}
queue<node> ans;
int cnt=0,max=-1;//一开始把max赋值为负数防治第一个上不去 非负有可能为0不能冲突(注意)
node maxnode;
for(int i=0;i<n;i++){
ans.push(vv[i]);
}
while(!ans.empty()){//队列标配(注意),隔着注释打大括号,下面的打不出来
if(ans.size()==1){
node temp=ans.front();
vv[temp.index] .rank=1;//索引出问题(注意)
ans.pop();
break;
}
int group=0,sn=ans.size();
if(sn%k==0) group=sn/k;//变量明明都没有瞎写(注意) //整除k居然忘写余数为0 sn%k==0
else group=sn/k+1;
for(int i=0;i<sn;i++){//注意每次只处理一轮的所以要引size
node temp=ans.front();
ans.pop();
vv[temp.index].rank=group+1;//胜出的还会再更新(注意)
cnt++;
if(temp.wei>max){//队列不能直接按下标索引 ,只能取队首
max=temp.wei;
maxnode=temp;
}
if(cnt==k||i==sn-1){
ans.push(maxnode);
max=-1;//赋值为-1,因为是数据非负不能冲突
cnt=0;
}
}
}
sort(vv.begin(),vv.end(),cmp);
printf("%d",vv[0].rank);
for(int i=1;i<vv.size();i++){
printf(" %d",vv[i].rank);
}
return 0;
}
总结
1. 看了大佬的思路后自己动手实现,有一些小错误,有一些大错误需要不断反思总结
2.题意理解一开始也理解偏了,output也没认真看,居然没有第四名,他这个定排名的顺序比较反常规
3.cmp , sn整除k sn%k==0,细节错误
4.思路是 利用队列,一开始要引一个变量,因为后面的操作会使通用变量发生变化,我们想要他没变之前的size,来区分各轮,push本轮要比的各组,各组的组别区分以cnt计数来分开,成功的嫁入queue中,作为下一轮进行比对,这里赋值rank要找规律与组数的关系,并且采用直接复制,虽然有些不正确,但后边的轮里会在覆盖为正确的值,这样直到找到size为1的,rank为1
存储的变量,vv中那个值index0就是最后顺序用的,之前使用的所有标号按照一开那个分组的随机顺序来,输出按照index0输出,怎么简单怎么来。
英语
问题
总结一下队列什么时候使用 使用的模板