修改数组
题目描述
给定一个长度为 𝑁 的数组𝐴=[𝐴1,𝐴2,⋅⋅⋅,𝐴𝑁],数组中有可能有重复出现的整数。
现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改𝐴2,𝐴3,⋅⋅⋅,𝐴𝑁
当修改 𝐴𝑖 时,小明会检查 𝐴𝑖 是否在 𝐴1 ∼ 𝐴𝑖−1 中出现过。如果出现过,则小明会给 𝐴𝑖 加上 1 ;如果新的 𝐴𝑖 仍在之前出现过,小明会持续给 𝐴𝑖 加 1 ,直 到 𝐴𝑖 没有在 𝐴1 ∼ 𝐴𝑖−1 中出现过。
当𝐴𝑁 也经过上述修改之后,显然 𝐴 数组中就没有重复的整数了。
现在给定初始的 𝐴 数组,请你计算出最终的 𝐴 数组。
输入描述
第一行包含一个整数 𝑁。
第二行包含 𝑁 个整数𝐴1,𝐴2,⋅⋅⋅,𝐴𝑁 。
其中,1≤𝑁≤105,1≤𝐴𝑖≤106 。
输出描述
输出 𝑁 个整数,依次是最终的 𝐴1,𝐴2,⋅⋅⋅,𝐴𝑁。
输入输出样例
示例
输入
5
2 1 1 3 4
输出
2 1 3 4 5
运行限制
最大运行时间:1s
最大运行内存: 256M
题解
难度不大哈
最初想到的肯定是暴力嘛,蓝桥杯有部分分,试了下,90分。(不行你送我10分呢?)分数相当可观,代码如下
#include<bits/stdc++.h>
using namespace std;
int n,a[100005];
bool flag[1000005];
int main(){
int i,j,k;
cin>>n;
for(i=1;i<=n;i++){
cin>>a[i];
if(!flag[a[i]]){
flag[a[i]]=1;
}
else {
while(flag[a[i]]==1)a[i]++;
}
flag[a[i]]=1;
printf("%d ",a[i]);
}
return 0;
}
然后嘛,你观察,a[i]没有半点用处,你就不需要算了,然后你看看啊,时间消耗在一个一个找的上面,那我们记录每个数的个数不就行了,每次加当前数的个数,速度也加快了,满分代码。代码如下
#include<bits/stdc++.h>
using namespace std;
int n,x,cnt[1000010]; //cnt[x]表示当前整数x出现的次数
int main(){
int i,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&x);
while(cnt[x]){
cnt[x]++;
x+=cnt[x]-1;
}
cnt[x]++;
printf("%d ",x);
}
return 0;
}
外卖店优先级
题目描述
"饱了么"外卖系统中维护着 𝑁 家外卖店,编号 1 ∼ 𝑁。每家外卖店都有 一个优先级,初始时 (0 时刻) 优先级都为 0。
每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减 到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。
如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果 优先级小于等于 3,则会被清除出优先缓存。
给定 𝑇 时刻以内的 𝑀 条订单信息,请你计算 𝑇 时刻时有多少外卖店在优 先缓存中?
输入描述
第一行包含 3 个整数 𝑁,𝑀,𝑇。
以下𝑀 行每行包含两个整数 𝑡𝑠,𝑖𝑑,表示 𝑡𝑠 时刻编号 𝑖𝑑 的外卖店收到一个订单。
其中,1≤𝑁,𝑀,𝑇≤105,1≤𝑡𝑠≤𝑇,1≤𝑖𝑑≤𝑁
输出描述
输出一个整数代表答案。
输入输出样例
示例
输入
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
输出
1
样例解释:
6 时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6, 加入优先缓存。所以是有 1 家店 (2 号) 在优先缓存中。
运行限制
最大运行时间:2s
最大运行内存: 256M
题解
模拟题,按照要求模拟就行了
下面这段题解来自老师,用了数据结构的map操作以及并查集的思想,相当巧妙
1,模拟题,使用C++做的,为了使用map模拟桶结构,如果使用二维数组模拟桶,空间复杂度太高。所以,就算使用C写,也得写个链表,然后使用链表数组模拟桶。
2,map<int,map<int,int> > v;
这个v就是桶。是下面这个的一个结构
时间点
1 5 77 88 99 xxx ………………………………
外卖店
1 x x x x x x ………………………………
2 x x x x x x ………………………………
……
……
n x x x x x x ………………………………
即v[i][j]里面存放的x,表示在j时刻,外卖店i收到的订单数量。
3,vector flag(n+1);标记数组,flag(i)标记外面店i是否在缓冲之中。
4, 根据题意读数据,利用map自动给外卖店和时间点排序
while(m–)
{
int ts,id;
cin>>ts>>id;
v[id][ts]++;
}
5,map<int,map<int,int> >::iterator r=v.begin();
for(;r!=v.end();++r)
{map<int,int>& tmp=r->second;
map<int,int>::iterator r1=tmp.begin();
int time=0,pro=0;
…
}
外层循环,遍历每个外卖店.局部变量time表示前一个时间点,pro表示前一个时间点,外卖店r->first的优先级。
6,
for(;r1!=tmp.end();++r1)
{
pro-=r1->first-1-time;
if(pro<0) pro=0;
if(pro<=3&&flag[r->first])flag[r->first]=0;
pro+=2*r1->second;
if(pro>5&&!flag[r->first])flag[r->first]=1;
time=r1->first;
}
内层循环,遍历当前外卖店的,每个增加订单的时间点。前3句,处理的是当前时刻(r1->first) 的前一刻(r1->first-1),外卖店r->first的优先级和是否位于缓冲区。后三句,处理的是当前时刻(r1->first) ,外卖店
r->first的优先级和是否位于缓冲区。
7, pro-=t-time;
if(pro<=3&&flag[r->first])flag[r->first]=0;
if(flag[r->first]) count++;
外层循环的后3句,相当于处理终止时刻t,外卖店r->first的优先级和是否位于缓冲区。
#include <map>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int n,m,t,count=0;
cin>>n>>m>>t;
map<int,map<int,int> > v;
vector<bool> flag(n+1);
while(m--)
{
int ts,id;
cin>>ts>>id;
v[id][ts]++;
}
map<int,map<int,int> >::iterator r=v.begin();
for(;r!=v.end();++r)
{
map<int,int>& tmp=r->second;
map<int,int>::iterator r1=tmp.begin();
int time=0,pro=0;
for(;r1!=tmp.end();++r1)
{
pro-=r1->first-1-time;
if(pro<0) pro=0;
if(pro<=3&&flag[r->first])flag[r->first]=0;
pro+=2*r1->second;
if(pro>5&&!flag[r->first])flag[r->first]=1;
time=r1->first;
}
pro-=t-time;
if(pro<=3&&flag[r->first])flag[r->first]=0;
if(flag[r->first]) count++;
}
cout<<count;
return 0;
}
下面提供暴力…所以你不会就暴力吧…
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <utility>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int N=1e5+10;
int n,m,T,res;
int last[N],score[N];
PII order[N];
bool st[N];
int main(){
scanf("%d%d%d",&n,&m,&T);//输入
for(int i=0;i<m;i++)scanf("%d%d",&order[i].x,&order[i].y);//输入
sort(order,order+m);
for(int i=0;i<m;i++){
int t=order[i].x, id=order[i].y;
score[id]-=t-last[id]-1;
if(score[id]<0)score[id]=0;
if(score[id]<=3)st[id]=false;
int j=i;
while(j<m && order[i]==order[j])j++;
int cnt=j-i;
i=j-1;
score[id]+=cnt*2;
if(score[id]>5)st[id]=true;
last[id]=t;
}
for(int i=1;i<=n;i++){
if(last[i]<T){
score[i]-=T-last[i];
if(st[i] && score[i]<=3)st[i]=false;
}
}
for(int i=1;i<=n;i++){
res+=st[i];
}
cout<<res;
return 0;
}