Codeforces Round #600 (Div. 2) - B. Silly Mistake(模拟)
2024-08-28 05:37:43
题意:有一个公司,每天有员工进出,$a[i]>0$时表示$a[i]$这个员工进入公司,$a[i]<0$时表示$-a[i]$这个员工出公司,公司对进出办公室有一些严格的规定
- 员工每天最多只能进入一次办公室
- 如果那天他没有进办公室的话,他显然不能离开
- 每天开始和结束时,办公室都是空的(员工不能呆在晚上),办公室也可能在一天中的任何时候都是空的
现在给你序列$a$($a[i] \neq 0$),问你是否能够把数组$a$分为几个相邻的子数组,使得每一个子数组员工的进出情况符合要求并输出每一个子数组的长度,或者输出$-1$表示不可能
思路:用一个数组$mk$标记某个人状态,$mk[i]=0$表示$i$号员工在这一天内还没有操作,$mk[i]=1$表示$i$号员工在这一天内已经进入办公室,$mk[i]=-1$表示$i$号员工在这一天内已经进入办公室并且出去了,$num$记录此时办公室的人数,如果$num=0$时则可以进入新的一天,同时需要用一个数组$p$记录这一天已经出去的员工编号,在进入新的一天时,则需要将这些员工的$mk[i]$变为$0$,中间出现不合法的情况直接跳出循环,输出$-1$
#include <iostream>
#include <algorithm>
#include <cstdio> using namespace std; const int N = ;
const int M = ; int n, a[N], mk[M];
int num, cnt, p[N];
int res[N], pos; int main()
{
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%d", &a[i]);
int flag = ; res[++pos] = ;
for (int i = ; i <= n; i++) {
if (a[i] > ) {
if ( == mk[a[i]]) {
mk[a[i]] = , num++;
}
else {
flag = ; break;
}
}
else {
if ( == mk[-a[i]]) {
mk[-a[i]] = -, num--;
p[++cnt] = -a[i];
if ( == num) {
for (int j = ; j <= cnt; j++) mk[p[j]] = ;
cnt = , res[++pos] = i;
}
}
else {
flag = ; break;
}
}
}
if ( != num) flag = ;
if (!flag) printf("-1\n");
else {
printf("%d\n", pos - );
for (int i = ; i <= pos; i++) {
printf("%d", res[i] - res[i - ]);
printf(i == pos ? "\n" : " ");
}
}
return ;
}
最新文章
- Direct3D 10学习笔记(一)——初始化
- iOS收到Push后播放声音和震动
- 网摘 窗体的旋转效果 wpf
- HDU 4668 Finding string (解析字符串 + KMP)
- HTTP响应代码
- OSChina 的URL类的源代码重写过程
- HttpSesstionActivationLIstener示例
- SQL 语句优化方法
- CSS规范—分类方法(NEC规范学习笔记)
- 调试器GDB的基本使用方法
- ASP.NET 验证码绘制
- SpringBoot无法书写主启动类的情况之一
- react实现tab切换效果
- Java计算器(结对)
- zope.interface 库学习一
- 解决npm ERR! Unexpected end of JSON input while parsing near的方法汇总
- udevadm命令详解
- (Dijkstra)迪杰斯特拉算法-最短路径算法
- JSONCPP to Visual Studio
- JAVA框架 Spring 依赖注入