/*
移动小球:
我有小球,从左到右一次编号为1,2,3,...,n
你可以执行两种指令:
A X Y表示把小球X移动到小球Y的左边,B X Y表示把小球X移动到小球Y的右边。指令保证合法,即X不等于Y。
输入小球个数n,指令条数m和m条指令,从左到右输出最后的序列。注意,n可能高达500000,而m可能高达100000
输入:
6 2
A 1 4
B 3 5
输出:
2 1 4 5 3 6
关键:建立单链表,添加左移和右移函数
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode
{
int iData;
struct LNode* next;
}LNode,*LinkList;
void move(LinkList list,int n1,int n2)
{
//先找到n1与n2的位置
LNode* q = list,*q1,*q2,*p1,*p2;//p1与p2是n1与n2前面一个节点指针
LNode* p = q->next;
int iPos1,iPos2;
while(p)
{
if(p->data == n1)
{
q1 = q;
p1 = q1->next;
}
else if(p->data == n2)
{
q2 = q;
p2 = q2->nxt;
}
q = p;
p = p->next;
}
//拆下n1
q1->next = p1->next;
//q2指向p1
q2->next = p1;
//p1指向p2
p1->next = p2;
}
//尾插法建立单链表
LinkList buildLinkList(LinkList list,int n)
{
LNode* rear = list;
for(int i = 1 ;i < n;i++)
{
LNode* newNode = (LNode*)malloc(sizeof(LNode));
newNode->iData = i;
rear->next = newNode;//尾插法建立单链表时,只需要将末尾指向新节点,再让末尾节点称为新节点即可
rear = newNode;
}
rear->next = NULL;//置最后一个节点为空
return list;
}
void moveBall()
{
int n,m;
while(EOF != scanf("%d %d",&n,&m))
{
//LinkList list;//单链表的头结点必须用malloc建立起来
LinkList list = (LinkList)malloc(sizeof(LNode));
list->iData = -1;
buildLinkList(list,n);
for(int i = 0 ; i < m;i++)
{
char ch[10];
int n1,n2;
scanf("%s %d %d",&ch,&n1,&n2);
if('A' == ch[0])//易错,这里scanf("%s")指令类型用%s是因为:用%d读取整数后,没有读取回车换行符,而后面的%c会读取换行符,用%s跳过换行符
{
move(list,n1,n2);//左移
}
else
{
move(list,n2,n1);//右移
}
}
LNode* front = list->next;
while(front)
{
printf("%d ",front->iData);
front = front->next;
}
}
}
int main(int argc,char* argv[])
{
system("pause");
return 0;
}
算法竞赛入门经典:第六章 数据结构基础 6.3移动小球
最新推荐文章于 2024-03-02 17:33:17 发布