pat-1056

需二刷

#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输出,怎么简单怎么来。

英语

 

 

 

问题

总结一下队列什么时候使用  使用的模板

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值