移动小球

原题地址

转载来源:https://blog.csdn.net/air_one/article/details/12683355

移动小球

时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte
总提交:760            测试通过:88

描述

你有一些小球,从左到右依次编号为1,2,3,…,n,如下图所示:

你可以执行两种指令。其中A X Y表示把小球X移动到小球Y左边,B X Y表示把小球X移动到小球Y右边。指令保证合法,即X不等于Y。
例如,在初始状态下执行A 1 4后,小球1被移动到小球4的左边,如下图所示:

如果再执行B 3 5,结点3将会移到5的右边,如下图所示:

输入

输入小球个数n。指令条数m和m条指令,注意,1≤n≤500000,0≤m≤100000。

输出

从左到右输出最后的小球序列。

样例输入

6 2
A 1 4
B 3 5

样例输出

2 1 4 5 3 6

题目来源

刘汝佳《算法竞赛入门经典》

这题比较坑,数据输入量太大,用cin会超时,用scanf还可以,这是我第一次遇到这种情况。

题解可以看刘汝佳的书。

#include<stdio.h>
#include<stdlib.h>
 
#define MAXN  500005
 
int lft[MAXN],rgt[MAXN];
 
int main()
{
  int p,q,i,n,m;
  char type[2];
  scanf("%d%d",&n,&m);
  for(i = 0; i <= n+1; i++)
  {
    lft[i] = i-1;
    rgt[i] = i+1;
  }
  for(i = 0; i < m; i++)
  {
    scanf("%s%d%d",type,&p,&q);
    rgt[lft[p]] = rgt[p];
    lft[rgt[p]] = lft[p];
    if(type[0] == 'A')
    {
      rgt[lft[q]] = p;
      lft[p] = lft[q];
      lft[q] = p;
      rgt[p] = q;
    }
    else
    {
      lft[rgt[q]] = p;
      rgt[p] = rgt[q];
      rgt[q] = p;
      lft[p] = q;
    }
  }
  int front = rgt[0];
  while(rgt[front] != n+1)
  {
    printf("%d ",front);
    front = rgt[front];
  }
  printf("%d\n",front);
  return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42373330/article/details/81808812