Mail.Ru Cup 2018 Round 1 B. Appending Mex
B. Appending Mex
Initially Ildar has an empty array. He performs nn steps. On each step he takes a subset of integers already added to the array and appends the mex of this subset to the array.
The mex of an multiset of integers is the smallest non-negative integer not presented in the multiset. For example, the mex of the multiset [0,2,3][0,2,3] is 11, while the mex of the multiset [1,2,1][1,2,1] is 00.
More formally, on the step mm, when Ildar already has an array a1,a2,…,am−1a1,a2,…,am−1, he chooses some subset of indices 1≤i1<i2<…<ik<m1≤i1<i2<…<ik<m (possibly, empty), where 0≤k<m0≤k<m, and appends the mex(ai1,ai2,…aik)mex(ai1,ai2,…aik) to the end of the array.
After performing all the steps Ildar thinks that he might have made a mistake somewhere. He asks you to determine for a given array a1,a2,…,ana1,a2,…,an the minimum step tt such that he has definitely made a mistake on at least one of the steps 1,2,…,t1,2,…,t, or determine that he could have obtained this array without mistakes.
Input
The first line contains a single integer nn (1≤n≤1000001≤n≤100000) — the number of steps Ildar made.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤1090≤ai≤109) — the array Ildar obtained.
Output
If Ildar could have chosen the subsets on each step in such a way that the resulting array is a1,a2,…,ana1,a2,…,an, print −1−1.
Otherwise print a single integer tt — the smallest index of a step such that a mistake was made on at least one step among steps 1,2,…,t1,2,…,t.
Examples
input
Copy
4 0 1 2 1
output
Copy
-1
input
Copy
3 1 0 1
output
Copy
1
input
Copy
4 0 1 2 239
output
Copy
4
題意:現在有個陣列,你可以操作n次。對於每一次,從數組裡任選數字構成一個子集,然後這個子集裡沒有出現的第一個最小的數字叫做mex(題目這麼規定的- -)。把這個mex追加到陣列末尾,那麼這個陣列就增加了一個。現在問你1-n步裡有沒有出錯的,陣列最初是空的。
思路:首先第一步,一定是0不多說了。我們推一下規律,想要得到數字x,如果0~x-1有空缺,那麼最小的一定不是x,所以推理結論是:想要得到x,必須有0~x-1所有數字。同時如果已經有0~x所有的了,那麼依然可以繼續得到0~x的任意一個。
比如0 1 2,我們可以得到新數字只有一個3,而已經出現過的任何一個數字都可以得到,選取0 2 得1 選取1 2 得0 選取0 1 得2。
我們只儲存當前已經出現過的最大值mmax,對於新數字,要麼是mmax+1,要麼是0~mmax任意一個數。這個結論很簡單。
都不是輸出當前步驟即可。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,a[100010],flag;
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int mmax=-1;
flag=0;
for(int i=1;i<=n;i++)
{
if(a[i]>mmax)
{
if((a[i]-1)!=mmax)
{
flag=1;
printf("%d\n",i);
break;
}
else mmax=a[i];
}
}
if(flag==0)printf("-1\n");
}
return 0;
}