20240403学习总结

1、P8685 [蓝桥杯 2019 省 A] 外卖店优先级

“饱了么”外卖系统中维护着 N 家外卖店,编号 1N。每家外卖店都有一个优先级,初始时 (0(0 时刻)优先级都为 00。

每经过 11 个时间单位,如果外卖店没有订单,则优先级会减少 11,最低减到 00;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 22。

如果某家外卖店某时刻优先级大于 55,则会被系统加入优先缓存中;如果优先级小于等于 33,则会被清除出优先缓存。

给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优先缓存中。

输入格式

第一行包含 3个整数 N 、 M 和 T。

以下 M 行每行包含两个整数 ts 和 id,表示ts 时刻编号 id 的外卖店收到。

一个订单。

输出格式

输出一个整数代表答案。

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int n,m,t;
int last[N],score[N];
struct node{
	int time;
	int id;
}d[N];
bool st[N];
bool cmp(node a,node b){
	if(a.time !=b.time )  return a.time<b.time ;
	return a.id <b.id ;
}
int main(){
	cin>>n>>m>>t;
	for(int i=0;i<m;i++)
	  cin>>d[i].time >>d[i].id ;
	sort(d,d+m,cmp);
	for(int i=0;i<m;){
		int j=i;
		while(j<m&&d[j].time==d[i].time&&d[j].id==d[i].id ) j++;
		int nt=d[i].time ;
		int nid=d[i].id ;
		int count=j-i;
		i=j;
		score[nid]-=nt-last[nid]-1;
		if(score[nid]<0)  score[nid]=0;
		if(score[nid]<=3)  st[nid]=false;
		score[nid]+=count*2;
		if(score[nid]>5)  st[nid]=true;
		last[nid]=nt;
	}
	for(int i=1;i<=n;i++){
		//检查最后有订单的时间
		if(last[i]<t){
			score[i]-=t-last[i];
			if(score[i]<=3)  st[i]=false;
		} 
		
	}
	int sum=0;
	for(int i=1;i<=n;i++){
		if(st[i]==true)  sum++;
	}
	cout<<sum;
	return 0;
}

2、P8686 [蓝桥杯 2019 省 A] 修改数组

题目描述

给定一个长度为 N 的数组 A=[A1​,A2​,⋯AN​],数组中有可能有重复出现的整数。

现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改 A2​,A3​,⋯,AN​。

当修改 Ai​ 时,小明会检查 Ai​ 是否在 A1​ ∼ Ai−1​ 中出现过。如果出现过,则小明会给 Ai​ 加上 1;如果新的 Ai​ 仍在之前出现过,小明会持续给Ai​ 加 11,直到 Ai​ 没有在 A1​ ∼ Ai−1​ 中出现过。

当 AN​ 也经过上述修改之后,显然 A 数组中就没有重复的整数了。

现在给定初始的 A 数组,请你计算出最终的 A 数组。

输入格式

第一行包含一个整数 N。

第二行包含 N 个整数 1,2,⋯ ,A1​,A2​,⋯,AN​。

输出格式

输出 N 个整数,依次是最终的 1,2,⋯ ,A1​,A2​,⋯,AN​。

思路:可以使用并查集来写复习一下并查集的两个代码

//查找根节点的代码
int find(int x){
 if(f[x]!=x)  f[x]=find(f[x]);
  return f[x];
}
//合并的代码
void join(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy)  f[fx]=fy;
}
#include<iostream>
using namespace std;
const long long N=100009;
long long f[N];
long long find(int x){
	if(f[x]!=x){
		f[x]=find(f[x]);
	}
	return f[x];
}
void join(int a,int b){
	int fx=find(a);
	int fy=find(b);
	if(fx!=fy){
		f[fx]=fy;
	}
}
int main(){
	long long n,p;
	scanf("%lld",&n);
	for(long long i=1;i<100009;i++)
	  f[i]=i;
	for(long long i=1;i<=n;i++){
		scanf("%lld",&p);
		p=find(p);
		printf("%lld ",p);
		join(p,p+1);
	}
	return 0;
}

3、P8716 [蓝桥杯 2020 省 AB2] 回文日期

找到日期符合回文日期,第二个日期符合ABABBABA

思路:从给出的日期向后找即可,找到第一个就可以,用found做标记

//关于处理日期的几个注意点
const int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31}
int runnian(int y){
if(y%4==0&&y%100!=0||y%400==0)  return 1;
return 0;
}

int getday(int y,int m){
if(m==2)  return 28+runnian(y);
return month[m];
}

void nextday(int& y,int& m,int& d){
d++;
if(d>getday(y,m){
   d=1;
   m++;
   if(m>12){
     m=1;
     y++;
}
}
}

//快速输入年月日的表示方式
scanf("%04d%02d%02d",&y,&m,&d);
//还有一个特殊的函数sprintf,可以快速赋值给字符串
char s[10]={0};
sprintf(s,"%04d%02d%02d",y,m,d);
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int y,m,d;
const int months[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int run(int y){
	if(y%4==0&&y%100!=0||y%400==0)
	  return 1;
	return 0;
}
int getday(int y,int m){
	if(m==2)  return 28+run(y);
	return months[m];
}
void nextday(int& y,int& m,int& d){
	d++;
	if(d>getday(y,m)){
		d=1;
		m++;
		if(m>12){
			m=1;
			y++;
		}
	}
}
bool check1(char s[]){
	//检查是不是回文日期的
	for(int i=0,j=7;i<j;i++,j--){
		if(s[i]!=s[j])  return false;
	} 
	return true;
}
bool check2(char s[]){
	//检查是不是ABABBABA
	char a=s[0],b=s[1],c=s[2],d=s[3];
	if(a==c&&b==d&&a!=b) return true;
     return false;
}
int main(){
	scanf("%04d%02d%02d",&y,&m,&d);
	char s[10]={0};
	bool found1=false,found2=false;
	while(!found1||!found2){
		nextday(y,m,d);
		sprintf(s,"%04d%02d%02d",y,m,d);
		if(check1(s)){
			if(!found1){
				puts(s);
				found1=true;
			}
			if(!found2&&check2(s)){
			
					puts(s);
					found2=true;
				
			}
		}
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值