ny511 移动小球

移动小球

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
 
描述
给你n个小球,从左到右编号依次为1,2,3,4,5,6.........n,并规定小球1的左边的球号为n,小球n的右边的球号为1.现在有以下3种操作:A x y表示把编号为x小球移动到编号为y的小球的左边,B x y表示把编号为x小球移动到编号为y的小球的右边,Q 1 m为询问编号为m的小球右边的球号,Q 0 m为询问编号为m的小球左边的球号。
 
输入
第一行有一个整数n(0<n<10000),表示有n组测试数据,随后每一组测试数据第一行是两个整数N,M,其中N表示球的个数(1<N<10000),M表示操作的的次数(0<M<10000)
随后的M行,每行有三个数 s x y,s表示操作的类型,x,y为小球号。当s为Q时,若x为1,则询问小球y右边的球号,x为0,则询问小球y左边的球号。
输出
输出每次询问的球号
样例输入
1
6 3
A 1 4
B 3 5
Q 1 5
样例输出
3
讲解:题意说,编号排一遍就固定了,不会变,所以,改变一次编号就乱了;
#include<stdio.h>
int A[10001];
int find(int n)//寻找本编号的号码,所在数组中的位置;
{
 int i;
 for(i = 1; i < 10001; i++)
  if(A[i] == n)
   return i;
}
void shift_circular_left(int x, int y)
{
 int t, m, n;
 t = A[x];
 n = x; m = y;
 while(n<=y-1)
 {
  A[n] = A[n+1];
  n++;
 }
 A[y] = t;
}
void shift_circular_right(int x, int y)
{
 int m,n,t;
 n=x;m=y;
 t = A[y];
 while(m>=x)
 {
  A[m] = A[m-1];
  m--;
 }
 A[x]=t;
}
int main()
{
 int i, j, m, q, p, n, t, a;
 char type;
 int x, y;
 scanf("%d", &t);
 while(t--)
 {
  scanf("%d%d", &n, &m);
  for(i = 1; i <= n; i++)
   A[i] = i;
  for(i = 0 ;i < m; i++)
  {
   getchar();
   scanf("%c%d%d", &type, &x,&y);
   p = find(x);//找到该编号的位置
   q = find(y);
   if(type == 'A')
    if(p < q)
     shift_circular_left(p, q-1);//左移;
    else
     shift_circular_right(q, p);//右移
else if(type == 'B')
    if(p < q)
     shift_circular_left(p, q);
    else
     shift_circular_right(q+1, p);
   else
   {
    y = q;
    if(x == 1)//输出该编号的号码所在的位置的右边的数
    {
     if(y==n)//如果排在最后一位,则它的右边是第一位
      a = A[1];
     else
      a = A[y+1];
    }
    else
    {
     if(y==1)//1的左边是n
      a = A[n];
     else
      a = A[y-1];
    }
    printf("%d ",a);
 //   for(j=1;j<=n;j++)
 //    printf("%d*******%d ",j,A[j]);
            }
  }
 }
 return 0;
}
原文地址:https://www.cnblogs.com/lovychen/p/3193908.html