A. Nauuo and Cards

https://codeforces.com/problemset/problem/1172/A


题目描述

Nauuo is a girl who loves playing cards.

One day she was playing cards but found that the cards were mixed with some empty ones.

There are nn cards numbered from 11 to nn , and they were mixed with another nn empty cards. She piled up the 2n2n cards and drew nn of them. The nn cards in Nauuo's hands are given. The remaining nn cards in the pile are also given in the order from top to bottom.

In one operation she can choose a card in her hands and play it — put it at the bottom of the pile, then draw the top card from the pile.

Nauuo wants to make the nn numbered cards piled up in increasing order (the ii -th card in the pile from top to bottom is the card ii ) as quickly as possible. Can you tell her the minimum number of operations?

输入格式

The first line contains a single integer nn ( 1\le n\le 2\cdot 10^51≤n≤2⋅105 ) — the number of numbered cards.

The second line contains nn integers a_1,a_2,\ldots,a_na1​,a2​,…,an​ ( 0\le a_i\le n0≤ai​≤n ) — the initial cards in Nauuo's hands. 00 represents an empty card.

The third line contains nn integers b_1,b_2,\ldots,b_nb1​,b2​,…,bn​ ( 0\le b_i\le n0≤bi​≤n ) — the initial cards in the pile, given in order from top to bottom. 00 represents an empty card.

It is guaranteed that each number from 11 to nn appears exactly once, either in a_{1..n}a1..n​ or b_{1..n}b1..n​ .

扫描二维码关注公众号,回复: 11603239 查看本文章

输出格式

The output contains a single integer — the minimum number of operations to make the nn numbered cards piled up in increasing order.

题意翻译

你的手上有 nn 张牌,牌堆中有 nn 张牌,共有 nn 张 00 牌,和 nn 张数字牌(从 11 到 nn)。定义一次“操作”为将手中的牌放到牌堆的底部,并把牌堆顶端的牌拿到手中,求使用最少的操作次数能够让牌堆中的牌变为 1,2,...,n1,2,...,n。

输入输出样例

输入 #1复制

3
0 2 0
3 0 1

输出 #1复制

2

输入 #2复制

3
0 2 0
1 0 3

输出 #2复制

4

输入 #3复制

11
0 0 0 5 0 0 0 4 0 0 11
9 2 6 0 8 1 7 0 3 0 10

输出 #3复制

18

说明/提示

Example 1

We can play the card 22 and draw the card 33 in the first operation. After that, we have [0,3,0][0,3,0] in hands and the cards in the pile are [0,1,2][0,1,2] from top to bottom.

Then, we play the card 33 in the second operation. The cards in the pile are [1,2,3][1,2,3] , in which the cards are piled up in increasing order.

Example 2

Play an empty card and draw the card 11 , then play 11 , 22 , 33 in order.


思路:刚看到的时候觉得是结论,看了下范围感觉是个模拟。最开始模拟还模拟错了...muliset+deque搞了半天发现出错了。

正解:比较显然的是最差的情况是2n(全部收集起来再打出),所以模拟肯定不会超时。

然后考虑<n和>=n的情况。

<n的情况:桌子上有一段连续的......1 2 3 4 ..x(末尾) 对于这种就判断一下能否达到打出一张同时收集到下一张刚好可以打出的。模拟一下,注意特判手牌全0的时候。

>=n的时候,当前手牌没有1的时候,肯定要先疯狂拿牌给0拿到1,然后这时候有了1怎么办呢?

比如 1 0 0 3 0

        0 5 0  2 4 当快拿到4的时候其实这时候把1打出去是最优的。也就是说在边拿边打。具体在什么时候打呢?这里怎么模拟呢?(当然你也可以直接用结论去做)

这就是这题给的模拟启发:先判有没有1,有了1,直接把1打出去,然后往队里压入0.然后去疯狂拿2,有了2再压入0。以此类推。这个过程就相当于把1留在手牌里,再到有了2能打的时候打出去。比较巧妙辣!.

(如果2不在手里,就要等2拿到之后再插入,相当于在1卡片的前面插入了0卡片,即1卡片插入的次数延后)

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef long long LL;
LL vis1[maxn],vis2[maxn];
deque<LL>q1,q2;
LL n,ans=0;
bool check()
{	
   LL t=0;
   while(t<n&&q1[t]!=1) t++;
   for(LL i=t+1;i<n;i++) if(q1[i]-q1[i-1]!=1) return false;
   if(t==0) return true;
   //判能不能刚好对应出完 
   	while(1)
	{  
	   LL tail=q1.back();
	   if(vis1[tail+1]>=1)
	   {
	   	  	 vis1[tail+1]=0;
			 q1.push_back(tail+1);
		  	 LL head=q1.front();
		  	 vis1[head]++;
			 q1.pop_front(); 
	   		 ans++;
	   		 if(vis1[0]==n) return true;
	   }	
	   else return false;  
   } 
}
void solve()
{
	cin>>n;
	for(LL i=1;i<=n;i++) {
		LL x;cin>>x;vis1[x]++;vis2[x]++;
	}
	for(LL i=1;i<=n;i++){
		LL x;cin>>x;q1.push_back(x);q2.push_back(x);
	}
	//判断<=n的情况是否满足
	bool flag=check();
	if(flag) 
	{
		cout<<ans<<endl;	
	}
	//模拟>n的情况 
	else
	{	
		ans=0;	
		for(LL i=1;i<=n;i++)
		{
			while(!vis2[i]) {if(q2.front()) vis2[q2.front()]=1; q2.pop_front();q2.push_back(0);ans++; }	
			if(q2.front()){ vis2[q2.front()]=1;}
			q2.pop_front();q2.push_back(i);ans++;
		}	
		cout<<ans<<endl;
	}	
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  solve();
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108425831