蓝桥杯第十届省赛A组(G~H)题(并查集)
G.

根据每个店的每一单进行处理即可。用一个vector记录每个店在哪个时间有订单,再对时间进行升序排序。令第一个订单的时间的优先度为2.下一个订单的优先度为下一个订单的时间和上一个的时间差。如果时间差为1或者0则不用减去直接加2即可。如果上一个订单的优先度减去时间差后小于0,则重置为0.如果减去时间差后小于等于3,则踢出优先缓存。需要注意的是需要特判一下该店一个订单都没有的情况,防止越界。
AC代码如下:
#include<bits/stdc++.h> #define MAXN 100005 using namespace std; typedef long long ll; typedef pair<int,int> pii; int n,m,t,s[MAXN],ans=0; vector<int>d[MAXN]; int main(){ scanf("%d%d%d",&n,&m,&t); for(int i=0;i<m;i++){ int t1,t2; scanf("%d%d",&t1,&t2); d[t2].push_back(t1); } for(int i=1;i<=n;++i){ int flag=0; memset(s,0,sizeof(s)); int len=d[i].size(); if(len==0) continue; sort(d[i].begin(),d[i].end()); s[d[i][0]]=2; for(int j=1;j<len;++j){ if(d[i][j]==d[i][j-1]) s[d[i][j]]=s[d[i][j-1]]+2; else{ s[d[i][j]]=s[d[i][j-1]]-(d[i][j]-d[i][j-1]-1); if(s[d[i][j]]<=3) flag=0; if(s[d[i][j]]<=0) s[d[i][j]]=2; else s[d[i][j]]+=2; } if(s[d[i][j]]>5) flag=1; // printf("第%d天是s[t]=%d\n",d[i][j],s[d[i][j]]); } if(d[i][len-1]!=t){ s[t]=s[d[i][len-1]]-(t-d[i][len-1]); if(s[t]<=3) flag=0; else if(s[t]>5) flag=1; } // printf("s[t]=%d\n",s[t]); if(flag) ++ans; } printf("%d",ans); return 0; }
H.

使用并查集查找最小的比该数大的值即可。
AC代码如下:
#include<iostream> #include<cstring> #include<algorithm> #define MAXN 100005 #define MAXM 1000005 using namespace std; typedef long long ll; int n,a[MAXN],fa[MAXM],vis[MAXM]; int find_f(int a){ while(vis[fa[a]]) fa[a]=find_f(fa[a]); return fa[a]; } int main(){ scanf("%d",&n); memset(fa,0,sizeof(fa)); memset(vis,0,sizeof(vis)); for(register int i=0;i<n;++i) scanf("%d",&a[i]); for(register int i=1;i<MAXM;++i) fa[i]=i+1; for(register int i=0;i<n;++i){ if(!vis[a[i]]) vis[a[i]]=1; else{ int temp=find_f(a[i]); a[i]=temp; vis[a[i]]=1; } } for(register int i=0;i<n;++i){ printf("%d ",a[i]); } return 0; }

浙公网安备 33010602011771号