POJ1208 ,来自UVA101题,注意读懂题目意思:
move a onto b: 先将a和b上的积木放回原来的位置,然后再将a放到b上面
move a over b: 先将a上的积木放回到原来的位置,然后将a放到b所在积木堆的顶部(b上的积木不动)
pile a onto b: 先将b上的积木放回原来的位置,再将a和a上的积木放到b上
pile a over b: 将a本身和其上的积木一起搬到到b所在的那堆积木之上
我作为四段读的,str1,num1,str2,num2。但判断的时候,str1只需要判断str[0],str2只需要判断str2[1]就可以区分命令了.
刚开始题目给的两个例样输出。程序对的,提交后RE,用clock测试了下,发现不可能超时。估计遇到了死循环,于是写了个随机生成测试数据的程序,按照逐步缩小范围的方法,最终确定了问题:原来在确定本题一个关键上——命令有可能是无效的(1.num1和num2相等。2.num1,num2在同一堆上)。我的BUG就在判断同一堆上了。少写了个一半,不严密。修改后AC了。
但奇怪的是POJ AC, UVA不能AC? 什么问题?随机生成1000组数据都可以测试出来的。
额,纠结于UVA, 这个系统很苛刻。。
typedef struct pile
{
int num;
struct pile *up;
struct pile *down;
}Node;
Node a[30];//题目告诉0<n<25,我刚开始设的是1000,保险.
Node init[30];
int n;
int main()
{
int is_column(int n1, int n2);
void Move_Onto(Node *A, Node *B);
void Move_Over(Node *A, Node *B);
void Pile_Onto(Node *A, Node *B);
void Pile_Over(Node *A, Node *B);
Node* Search(int m);
int i, num1, num2;
char str1[5], str2[5];
Node *d, *A, *B;
while (scanf("%d", &n)==1)
{
for (i=0; i<n; i++)
{
a[i].num = i;
a[i].up = NULL;
a[i].down = NULL;
init[i].up = &a[i];
}
while (scanf("%s", str1), str1[0]!='q')
{
scanf("%d%s%d", &num1, str2, &num2);
if (num1==num2 || is_column(num1, num2))
{
continue;
}
A = Search(num1);
B = Search(num2);
if (str1[0]=='m' && str2[1]=='n')//Move_Onto
{
Move_Onto(A, B);
}
else if (str1[0]=='m' && str2[1]=='v')//Move_Over
{
Move_Over(A, B);
}
else if (str1[0]=='p' && str2[1]=='n')//Pile_Onto
{
Pile_Onto(A, B);
}
else//Pile_Over
{
Pile_Over(A, B);
}
}//while(!quit)
for (i=0; i<n; i++)
{
printf("%d:", i);
d = init[i].up;
while(d != NULL)
{
printf(" %d", d->num);
d = d->up;
}
printf("/n");
}
}
return 0;
}
Node* Search (int m)
{
Node *d;
int i;
for (i=0; i<n; i++)
{
d = init[i].up;
while (d)
{
if (d->num == m)
{
break;
}
d = d->up;
}
if (d)
{
return d;
}
}
return NULL;
}
int is_column(int n1, int n2)
{
Node *A, *B;
A = Search(n1);
B = Search(n2);
while(B->up)
{
if (B->num==A->num)
{
return 1;
}
B = B->up;
}
while(B->down)
{
if (B->num==A->num)
{
return 1;
}
B = B->down;
}
while(A->up)
{
if (B->num==A->num)
{
return 1;
}
A = A->up;
}
while(A->down)
{
if (B->num==A->num)
{
return 1;
}
A = A->down;
}
return 0;
}
void Move_Onto(Node *A, Node *B)
{
Node *d, *initd;
d = A;
while (d->up)//找A最上面的点
{
d = d->up;
}
while (d!= A)
{
initd = &init[d->num];//找到最上面的点的原来位置
while (initd->up)//找原来位置最上面的点
{
initd = initd->up;
}
initd->up = d;//将A最上面的点挪回原位置的最上面
d = d->down;//准备挪下一个位置
d->up->down = initd;//将原位置最上的点指向新的原位置最上的点
d->up = NULL;
}
d = B;
while (d->up)
{
d = d->up;
}
while (d!= B)
{
initd = &init[d->num];
while (initd->up)
{
initd = initd->up;
}
initd->up = d;
d = d->down;
d->up->down = initd;
d->up = NULL;
}
B->up = A;//A挪到B上
if (A->down == NULL)//如果A为最下面的一个点,则只剩头结点
{
init[A->num].up = NULL;
}
else
{
A->down->up = NULL;
}
A->down = B;
}
void Move_Over(Node *A, Node *B)
{
Node *d, *initd;
d = A;
while (d->up)
{
d = d->up;
}
while (d!= A)
{
initd = &init[d->num];
while (initd->up)
{
initd = initd->up;
}
initd->up = d;
d = d->down;
d->up->down = initd;
d->up = NULL;
}
d = B;
while (d->up)
{
d = d->up;
}
d->up = A;
if (A->down == NULL)
{
init[A->num].up = NULL;
}
else
{
A->down->up = NULL;
}
A->down = d;
}
void Pile_Onto(Node *A, Node *B)
{
Node *d, *initd;
d = B;
while (d->up)
{
d = d->up;
}
while (d!= B)
{
initd = &init[d->num];
while (initd->up)
{
initd = initd->up;
}
initd->up = d;
d = d->down;
d->up->down = initd;
d->up = NULL;
}
B->up = A;
if (A->down == NULL)
{
init[A->num].up = NULL;
}
else
{
A->down->up = NULL;
}
A->down = B;
}
void Pile_Over(Node *A, Node *B)
{
Node *d;
d = B;
while (d->up)
{
d = d->up;
}
d->up = A;
if (A->down == NULL)
{
init[A->num].up = NULL;
}
else
{
A->down->up = NULL;
}
A->down = d;
}
下面是数据生成器:
double random()
{
return (double) rand() / RAND_MAX;
}
int rando(int m)
{
return (int)(random() * (m-1) + 0.5);
}
int main()
{
int n, i, m, ci;
freopen("in.txt", "w", stdout);
srand(time(NULL));
scanf("%d", &n);
for (i=0; i<n; i++)
{
m = rand()%50+1;
printf("%d/n", m);
ci = rand()%50+1;
while (ci--)
{
if (rand()%2 ==0)
{
printf("move");
}
else
{
printf("pile");
}
printf(" ");
printf("%d",rando(m));
printf(" ");
if (rand()%2 ==0)
{
printf("onto");
}
else
{
printf("over");
}
printf(" ");
printf("%d",rando(m));
printf("/n");
}
printf("quit/n");
}
return 0;
}