B.silly mistake

B. Silly Mistake
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
The Central Company has an office with a sophisticated security system. There are 106 employees, numbered from 1 to 106.

The security system logs entrances and departures. The entrance of the i-th employee is denoted by the integer i, while the departure of the i-th employee is denoted by the integer −i.

The company has some strict rules about access to its office:

An employee can enter the office at most once per day.
He obviously can’t leave the office if he didn’t enter it earlier that day.
In the beginning and at the end of every day, the office is empty (employees can’t stay at night). It may also be empty at any moment of the day.
Any array of events satisfying these conditions is called a valid day.

Some examples of valid or invalid days:

[1,7,−7,3,−1,−3] is a valid day (1 enters, 7 enters, 7 leaves, 3 enters, 1 leaves, 3 leaves).
[2,−2,3,−3] is also a valid day.
[2,5,−5,5,−5,−2] is not a valid day, because 5 entered the office twice during the same day.
[−4,4] is not a valid day, because 4 left the office without being in it.
[4] is not a valid day, because 4 entered the office and didn’t leave it before the end of the day.
There are n events a1,a2,…,an, in the order they occurred. This array corresponds to one or more consecutive days. The system administrator erased the dates of events by mistake, but he didn’t change the order of the events.

You must partition (to cut) the array a of events into contiguous subarrays, which must represent non-empty valid days (or say that it’s impossible). Each array element should belong to exactly one contiguous subarray of a partition. Each contiguous subarray of a partition should be a valid day.

For example, if n=8 and a=[1,−1,1,2,−1,−2,3,−3] then he can partition it into two contiguous subarrays which are valid days: a=[1,−1 | 1,2,−1,−2,3,−3].

Help the administrator to partition the given array a in the required way or report that it is impossible to do. Find any required partition, you should not minimize or maximize the number of parts.

Input
The first line contains a single integer n (1≤n≤105).

The second line contains n integers a1,a2,…,an (−106≤ai≤106 and ai≠0).

Output
If there is no valid partition, print −1. Otherwise, print any valid partition in the following format:

On the first line print the number d of days (1≤d≤n).
On the second line, print d integers c1,c2,…,cd (1≤ci≤n and c1+c2+…+cd=n), where ci is the number of events in the i-th day.
If there are many valid solutions, you can print any of them. You don’t have to minimize nor maximize the number of days.

Examples
inputCopy
6
1 7 -7 3 -1 -3
outputCopy
1
6
inputCopy
8
1 -1 1 2 -1 -2 3 -3
outputCopy
2
2 6
inputCopy
6
2 5 -5 5 -5 -2
outputCopy
-1
inputCopy
3
-8 1 1
outputCopy
-1
Note
In the first example, the whole array is a valid day.

In the second example, one possible valid solution is to split the array into [1,−1] and [1,2,−1,−2,3,−3] (d=2 and c=[2,6]). The only other valid solution would be to split the array into [1,−1], [1,2,−1,−2] and [3,−3] (d=3 and c=[2,4,2]). Both solutions are accepted.

In the third and fourth examples, we can prove that there exists no valid solution. Please note that the array given in input is not guaranteed to represent a coherent set of events.
题目大意:
中央公司有一个拥有复杂安全系统的办公室。确实有106雇员,编号:1到106.

安全系统记录出入口和出入口。入口处i-th Employee由整数表示i,而离开的时候i-th Employee由整数表示−i.

该公司对进入其办公室有一些严格的规定:

雇员可以进入办公室顶多每天一次。
如果那天早些时候不进去,他显然不能离开办公室。
在开始和结束的每一天,办公室是空的(员工不能呆在晚上)。在一天中的任何时刻,它也可能是空的。
满足这些条件的任何事件数组都称为有效日.

有效或无效天数的一些例子:

[1,7,−7,3,−1,−3]是有效的一天(1进入,7进入,7树叶,3进入,1树叶,3)。
[2,−2,3,−3]也是有效的一天。
[2,5,−5,5,−5,−2]是不有效的一天,因为5同一天两次进入办公室。
[−4,4]是不有效的一天,因为4没在办公室就离开了办公室。
[4]是不有效的一天,因为4在一天结束前没有离开办公室。
解析:
必须把这个序列划分成多天
例如:a = [1, -1, 1, 2, -1, 2, 3, -3]可以被划分成[1, -1| 1, 2, -1, -2, 3, -3],
即两天。
如果没有有效的划分,输出-1
如果有有效的划分,输出划分的天数和每段的元素个数,如果有多个答案,输出一种就行(暗示贪心)。
分析:解决这个问题有一种直观的贪心做法,模拟序列的进出,只要办公室出现一次空的,就记录划分的段数。
我们可以给予数组中每个雇员三种状态:进入办公室/在办公室里/离开办公室
每当我们结束一天,只需要重置参与的员工的状态
AC代码:
#include
#include
#include
#include
#include
using namespace std;
const int N=1000010;
int n;
vector off;
vector sect;
int state[N];
const int wait=0,leave=2,enter=1;
int solve()
{
scanf("%d",&n);
int len=0;
int employ;
for(int i=1;i<=n;++i)
{
cin>>employ;
int guy=abs(employ);
off.push_back(guy);
if(employ>0)//
{
if(state[guy]!=wait)
return false;
state[guy]=enter;
++len;
}
else{
if(state[guy]!=enter)
return false;
state[guy]=leave;
–len;
}
if(len==0)
{
sect.push_back(off.size());
for(int x:off)
state[x]=wait;
off.clear();
}
}
if(off!=empty())
return false;

int   countDays=sect.size();
cout<<countDays<<endl;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值