专栏文章
题解:P8188 [USACO22FEB] Email Filing S
P8188题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min3nkrg
- 此快照首次捕获于
- 2025/12/01 20:02 3 个月前
- 此快照最后确认于
- 2025/12/01 20:02 3 个月前
思路
对于这道题,根据题目描述可以判断出这是一道模拟题。
首先我们注意到,文件夹和邮件是两栏,可以分别翻动。
文件夹是不可以往上翻的,而邮件可以,所以我们要先选定要填充的文件夹,当该文件夹填充满了,就可以处理下一个文件夹了。
定义一个指针窗口,指向邮件,如果在该窗口不能继续归档或更换处理文件夹了,就可以更新该指针窗口。
注意跳过已经归档的邮件。
代码详解
CPP#include <bits/stdc++.h>
using namespace std;
#define int long long
int T;
const int MAXN=1e5+5;
int a[MAXN];
bool vis[MAXN];
int num[MAXN],con[MAXN];
signed main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>T;
while(T--) {
memset(a,0,sizeof(a));
memset(vis,0,sizeof(vis));
memset(num,0,sizeof(num));
memset(con,0,sizeof(con));
int cnt=0;
int st=0,ed=0,now=0;
int m,n,k;
cin>>m>>n>>k;
if(k==n||k==m) {
cout<<"YES"<<"\n";
continue;
}
//这里在输入时记录每个文件夹应有的数量
for(int i=1; i<=n; i++) cin>>a[i],num[a[i]]++;
now=1,st=1,ed=k;
//now记录处理的文件夹
//st为窗口起点,ed为窗口终点
while(cnt<n) {
bool flag=0;
//flag记录是否有操作
for(int i=st; i<=ed; i++) {
if(vis[i]) continue;
if(a[i]>=now&&a[i]<=now+k-1) {
cnt++;
vis[i]=1;
con[a[i]]++;
flag=1;
if(ed<n){
do ed++;
while(vis[ed]);
}
else {
do st--;
while(vis[st]);
}
//do-while去除已归档的邮件
}
}
while(con[now]==num[now]) flag=1,now++;
while(vis[st]) st++;
while(vis[ed]) ed++;
//更新指针窗口
if(!flag) {
if(ed<n) {
int right=ed;
while(st<=right) {
do st++;
while(vis[st]);
do ed++;
while(vis[ed]);
}
}
else break;
}
}
if(cnt==n) cout<<"YES"<<"\n";
else cout<<"NO"<<"\n";
}
return 0;
}
完结撒花。
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...