坑点
首先 设定的数值就很有意思
value<=3的时候 从缓冲队列释放 value>5的时候 放入缓冲队列
每次有外卖的时候加2分
那如果我value=3 不是刚好卡在中间??
这也是优先级减小和优先级增加的先后顺序 会对结果产生影响的原因
详细解释
假设当前节点为id 且当前时间点刚开始的时候 优先级为3
且节点id之前在缓冲队列中 满足f[id]=1
1.正常流程
因为时间点刚开始的时候 优先级为3
节点id从队列中释放f[id]=0
然后有外卖订单 优先级变为5 f[id]仍保持为从1变成0的结果
2.若先加分再判断
那么相当于时间点刚开始的时候
我们就有了3+2=5的优先级
f[id]=1的结果不变
也就是造成了影响!!!!!
所以这道题目一定要想清楚
判断是否出队是在时间点刚开始的时候!!
优先级增加是在时间点结束的时候!!!
(最后附上正解和wa了好多发的代码 有兴趣的大家自己比对一下)
正解
#include <iostream>
#include <algorithm>
using namespace std;
#define x first
#define y second
const int N=1e5+10;
int v[N],last[N];// v数组记录优先级 last数组记录上一次操作的时间
bool f[N];//f数组标记是否在缓冲队列中
vector<pair<int,int> >q;
int main(){
int n,m,t; cin>>n>>m>>t;
for(int i=0;i<m;i++){
pair<int,int> cur;
cin>>cur.x>>cur.y;
q.push_back(cur);
}
sort(q.begin(),q.end());//按照时间排序
for(auto cur:q){
if(cur.x>t) break;
//cout<<"cur v: "<<cur.x<<" "<<cur.y<<endl;
if(cur.x == last[cur.y]) v[cur.y]+=0;//前后时间相同 不减分
else
v[cur.y]=max(v[cur.y]-(cur.x-last[cur.y]-1),0);//减分 最小值>=0
if(v[cur.y]<4) f[cur.y]=0;//这一个判断必须放在v[cur.y]+=2前面 参考v=3
v[cur.y]+=2;//这个时刻即将结束 开始加分
if(v[cur.y]>5) f[cur.y]=1;
last[cur.y]=cur.x;
}
int res=0;
for(int i=1;i<=n;i++){
if(t!=last[i])//最后更新一波优先级
v[i]=max(v[i]-(t-last[i]),0);
if(v[i]>5 || (f[i]&&v[i]>=4)) res++;
}
cout<<res;
return 0;
}
错误代码
#include <iostream>
#include <algorithm>
using namespace std;
#define x first
#define y second
const int N=1e5+10;
int v[N],last[N];
bool f[N];
vector<pair<int,int> >q;
int main(){
int n,m,t; cin>>n>>m>>t;
for(int i=0;i<m;i++){
pair<int,int> cur;
cin>>cur.x>>cur.y;
q.push_back(cur);
}
sort(q.begin(),q.end());
for(auto cur:q){//比较这个for循环的代码
if(cur.x>t) break;
if(cur.x == last[cur.y]) v[cur.y]+=2;
else
v[cur.y]=max(v[cur.y]-(cur.x-last[cur.y]),0)+2;
last[cur.y]=cur.x;
if(v[cur.y]<4) f[cur.y]=0;
if(v[cur.y]>5) f[cur.y]=1;
}
int res=0;
for(int i=1;i<=n;i++){
v[i]=max(v[i]-(t-last[i]-1),0);
if(v[i]>5 || (f[i]&&v[i]>=4)) res++;
}
cout<<res;
return 0;
}
谢谢大佬
感谢,改了好久才发现是这里
谢谢,改了判断顺序就过了。
终于知道自己为什么过不完所有样例了,感谢