比赛 HAOI2009 模拟试题2 评测结果 WWWWWEWTTE
题目名称 可可的文本编辑器 最终得分 0
用户昵称 BYVoid 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2009-04-22 11:29:20
显示代码纯文本
/* 
 * Problem: HAOI2009模拟2 editor
 * Author: Guo Jiabao
 * Time: 2009.4.22 9:47
 * State: Done
 * Memo: 块状链表
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXC=1050,Limit=1024;
using namespace std;
struct block
{
	char array[MAXC];
	int len;
	block *ad[2];
}*first,*P_b;
struct index
{
	block *B;
	int P;
}Id[MAXC*MAXC];
char C[MAXC*MAXC];
int N,P_c,Ic;
block* newblock()
{
	block *p=new block();
	p->len=0;
	p->ad[0]=p->ad[1]=0;
	return p;
}
void BlockList_Prev()
{
	if (P_b==first && P_c==1)
		return;
	P_c--;
	if (P_c==0)
	{
		P_b=P_b->ad[0];
		P_c=P_b->len-1;
	}
}
void BlockList_Next()
{
	if (P_c==P_b->len-1 && !P_b->ad[1])
		return;
	P_c++;
	if (P_c==P_b->len)
	{
		P_b=P_b->ad[1];
		P_c=1;
	}
}
void Blocklist_Merge(block *b1,block *b2)
{
	for (int p=1;p<=b2->len;p++)
		b1->array[ ++b1->len ]=b2->array[p];
	if (b2->ad[1])
		b2->ad[1]->ad[0]=b1;
	b1->ad[1]=b2->ad[1];
	delete b2;
	b1->array[b1->len+1]=0;
}
void BlockList_Delete(int len)
{
	block *B=P_b,*e,*f;
	int i,p=P_c;
	if (p + len - 1 <= B->len)
	{
		for (i=p+len;i<=B->len;i++)
			B->array[i-len]=B->array[i];
		B->len-=len;
		B->array[B->len+1]=0;
		BlockList_Prev();
		BlockList_Next();
	}
	else
	{
		len -= B->len - p;
		B->len=p-1;
		for (e=B->ad[1];e;e=f)
		{
			if (len - e->len <=0)
			{
				for (i=len+1;i<=e->len;i++)
					e->array[i-len]=e->array[i];
				e->len-=len;
				break;
			}
			if (e->ad[1])
				e->ad[1]->ad[0]=e->ad[0];
			e->ad[0]->ad[1]=e->ad[1];
			len -= e->len;
			f=e->ad[1];
			delete e;
		}
	}
	if (B->ad[1] && B->ad[1]->len + B->len <=Limit)
		Blocklist_Merge(B,B->ad[1]);
}
void BlockList_Insert(int len)
{
	block *B=P_b,*tail;
	int i,p=P_c;
	tail=newblock();
	for (i=p;i<=B->len;i++)
		tail->array[++tail->len]=B->array[i];
	tail->ad[1]=B->ad[1];
	if (tail->ad[1])
		tail->ad[1]->ad[0]=tail;
	B->len=p-1;
	for (i=1;i<=len;i++)
	{
		B->array[++B->len]=C[i];
		if (B->len>Limit)
		{
			B->array[B->len+1]=0;
			B->ad[1]=newblock();
			B->ad[1]->ad[0]=B;
			B=B->ad[1];
		}
	}
	B->array[B->len+1]=0;
	B->ad[1]=tail;
	tail->ad[0]=B;
	if (B->ad[1] && B->ad[1]->len + B->len <=Limit)
		Blocklist_Merge(B,B->ad[1]);
}
void BlockList_Rotate(int len)
{
	if (!len) return;
	block *B=P_b;
	int i=0,j=P_c;
	for (;i<len && B;B=B->ad[1])
	{
		for (;j<=B->len;j++)
		{
			C[++i]=B->array[j];
			if (i==len)
				break;
		}
		j=1;
	}
	for (i=1,j=len;i<j;i++,j--)
	{
		char c=C[i];
		C[i]=C[j];
		C[j]=c;
	}
	BlockList_Delete(len);
	BlockList_Insert(len);
}
void BlockList_Move(int p)
{
	block *B=first,*e;
	p++;
	int l=0;
	for (;B;B=e)
	{
		if (l+B->len > p)
		{
			P_b=B;
			P_c=p-l;
			break;
		}
		l+=B->len;
		e=B->ad[1];
		if (B->ad[0] && B->ad[0]->len + B->len <=Limit)
			Blocklist_Merge(B->ad[0],B);
	}
}
char BlockList_Get()
{
	return P_b->array[P_c];
}
void init()
{
	freopen("editor.in","r",stdin);
	freopen("editor.out","w",stdout);
	scanf("%d",&N);
	P_c=1;
	P_b=first=newblock();
}
void solve()
{
	int i,j,k,c;
	for (i=1;i<=N;i++)
	{
		scanf("%s",C);
		if (C[0]=='I')
		{
			scanf("%d",&k);
			do c=getchar();
			while (c!=10 && c!=13);ungetc(c,stdin);
			do c=getchar(); 
			while (c==10 || c==13);ungetc(c,stdin);
			C[0]=' ';
			for (j=1;j<=k;j++)
				C[j]=getchar();
			C[k+1]=0;
			BlockList_Insert(k);
		}
		else if (C[0]=='M')
		{
			scanf("%d",&k);
			BlockList_Move(k);
		}
		else if (C[0]=='D')
		{
			scanf("%d",&k);
			BlockList_Delete(k);
		}
		else if (C[0]=='R')
		{
			scanf("%d",&k);
			BlockList_Rotate(k);
		}
		else if (C[0]=='P')
			BlockList_Prev();
		else if (C[0]=='N')
			BlockList_Next();
		else
			printf("%c\n",BlockList_Get());
	}
}
int main()
{
	init();
	solve();
	return 0;
}