[bzoj1106][乱搞]立方体大作战tet

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Rose_max/article/details/82895916

Description

一个叫做立方体大作战的游戏风靡整个Byteotia。这个游戏的规则是相当复杂的,所以我们只介绍他的简单规
则:给定玩家一个有2n个元素的栈,元素一个叠一个地放置。这些元素拥有n个不同的编号,每个编号正好有两个
元素。玩家每次可以交换两个相邻的元素。如果在交换之后,两个相邻的元素编号相同,则将他们都从栈中移除,
所有在他们上面的元素都会掉落下来并且可以导致连锁反应。玩家的目标是用最少的步数将方块全部消除。

Input

第一行包含一个正整数n(1<=n<=50000)。接下来2n行每行一个数ai,从上到下描述整个栈,保证每个数出现且
仅只出现两次(1<=ai<=n)。初始时,没有两个相同元素相邻。并且保证所有数据都能在1000000步以内出解。

Output

第一行包含一个数m,表示最少的步数。

Sample Input

样例输入1

5

5

2

3

1

4

1

4

3

5

2

样例输入2

3

1

2

3

1

2

3

Sample Output

样例输出1

2

样例输出2

3

题解

显然如果两个数之间没有两个相同的数字
这两个数要消掉,肯定至少要交换他们距离那么多次
拿一个栈压一下
消掉两个数的代价,相当于他们的距离-他们之间能被消掉的数的对数
乱搞就好了

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#define LL long long
#define mp(x,y) make_pair(x,y)
using namespace std;
inline int read()
{
	int f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
inline void write(int x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
inline void print(int x){write(x);printf(" ");}
int n,sta[51000],tp;
int pos[51000],s[51000];
int lowbit(int x){return x&-x;}
void change(int x,int c){for(int i=x;i<=n;i+=lowbit(i))s[i]+=c;}
int findsum(int x){int ret=0;for(int i=x;i>=1;i-=lowbit(i))ret+=s[i];return ret;}
int main()
{
	n=read();
	int ans=0;
	for(int i=1;i<=2*n;i++)
	{
		int x=read();
		if(!pos[x])sta[++tp]=x,pos[x]=tp;
		else
		{
			 ans+=tp-pos[x]-findsum(pos[x]);
			 change(1,1);change(pos[x],-1);
		}
	}
	printf("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Rose_max/article/details/82895916