L2-034 口罩发放 (vector map) 代码段有详细解析

L2-034 口罩发放 (25 分)

为了抗击来势汹汹的 COVID19 新型冠状病毒,全国各地均启动了各项措施控制疫情发展,其中一个重要的环节是口罩的发放。

某市出于给市民发放口罩的需要,推出了一款小程序让市民填写信息,方便工作的开展。小程序收集了各种信息,包括市民的姓名、身份证、身体情况、提交时间等,但因为数据量太大,需要根据一定规则进行筛选和处理,请你编写程序,按照给定规则输出口罩的寄送名单。

/*
结构体存储每天的数据;
vector<>存储发烧人员
map<string,int>对人员id进行标记(身份证唯一性)
用m1,m2,一个标记有收到口罩的人
        一个标记发烧人员的输出 
具体看代码解析 
*/ 


#include<bits/stdc++.h>
using namespace std;
bool Panduan(string s)//判断身份证信息 
{
	int length=s.size();
	if(length!=18) return false;//是不是18位 
	else
	{
		for(int i=0;i<18;i++)
		{
			if(s[i]<'0'||s[i]>'9')//是不是都是数字 
			{
				return false;
			}
		}
	}
	return true;
}
struct P{
	string Name;
	string Id;
	int status;
	int hh,mm;//时间 (排序) 
	int num;//登记的序号 (排序) 
};
vector<struct P> v;//存储发烧的人员 
bool cmp(struct P a,struct P b)//对时间进行排序 
{
	if(a.hh!=b.hh) return a.hh <b.hh ;
	else if(a.mm!=b.mm) return a.mm<b.mm;
	else return a.num<b.num;
}
int main(void)
{
	int n,m;//天数、间隔 
	cin>>n>>m;
	int x,y;//人数、口罩数 
	map<string,int> m1,m2;//m1记录人发放时间间隔、m2标记发烧人的输出(每人仅输出一次) 
	for(int i=1;i<=n;i++)
	{
		cin>>x>>y;
		struct P p[x];//存储每天符合格式的人 (也可以用vector) 
		int s=0;//记录能发口罩的人数 
		for(int j=0;j<x;j++)
		{
			string name,id;
			int status,hh,mm;
			cin>>name>>id>>status;
			getchar();
			scanf("%d:%d",&hh,&mm);
			if(!Panduan(id)) continue;//Id错误,不记录 
			else
			{
				p[s].Name=name;
				p[s].Id=id;
				p[s].status=status;
				p[s].hh=hh;
				p[s].mm=mm;
				p[s].num=s;
				if(status==1) v.push_back(p[s]);//记录发烧的 
				s++;//人员++ 
			}
		}
		sort(p,p+s,cmp);//对排队时间进行排序 
		
		//我没有把所有发放记录都记录
		//而是当天发口罩就当天输出发放记录
		 
		for(int j=0;j<s&&y>0;j++)//按条件发口罩 
		{	//要么一次没发过,要么发过了要间隔 m 天 
			if(m1[p[j].Id]==0||m1[p[j].Id]+m+1<=i) 
			{
				cout<<p[j].Name<<" "<<p[j].Id<<endl;
				y--;//口罩-- 
				m1[p[j].Id]=i;//给谁发口罩就记录日期 
			}
		}
	}
	//用map<string ,int> m2进行输出标记 
	for(auto & it:v)//输出发烧的人 
	{
		if(m2[it.Id]!=0) continue;//输出过了就跳过 
		else
		{
			cout<<it.Name<<" "<<it.Id<<endl;
			m2[it.Id]++;//只要没输出,就++ 
		}
	}
	return 0;
}

以上代码是测试点都过了。

但是我有一个疑惑:本来我的cmp函数是这么写的

bool cmp(struct P a,struct P b)//对时间进行排序 
{
	if(a.hh!=b.hh) return a.hh <b.hh ;
	else  return a.mm<b.mm;
	
}

但是测试点4,5过不了。

我以为sortstruct进行排序的时候,如果时间相等的话,那么他也不会对源数据的顺序进行修改。于是我写了测试代码,如下:

/*
用sort进行排序时,在不符合排序规则的情况下
会改本原本数组的顺序吗?
 
 
下列的程序中,当a,b的值相等时,并不会改变原本
数据的前后关系。 
*/ 
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
struct P{
	int num;
	int a,b,c;
}p[100];
bool cmp(struct P x,struct P y)
{
	if(x.a!=y.a ) return x.a <y.a ;
	else return x.b<y.b;
}
int main(void)
{
	for(int i=0;i<6;i++)
	{
		p[i].num=i;
		cin>>p[i].a>>p[i].b>>p[i].c;
	}
	sort(p,p+6,cmp);
	for(int i=0;i<6;i++)
	{
		cout<<p[i].num<<' '<<p[i].a<<' '<<p[i].b<<" "<<p[i].c<<endl;
	}
	return 0;
}
/*
2 4 7
2 4 5
2 4 8
2 4 6
2 4 9
2 4 0


*/ 

结果显示,确实不会对源数据进行修改。

那么我这个排序明显也符合题目规定的“如果提交时间相同,则按照在列表中出现的先后顺序决定。”这个要求,那为什么测试点4 ,5过不了呢?

如果有知道的大神,望告知。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头秃不是梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值