101 - The Blocks Problem

All about problems in Volume 1. If there is a thread about your problem, please use it. If not, create one with its number in the subject.

Moderator: Board moderators

StepLg
New poster
Posts: 6
Joined: Wed Dec 28, 2005 10:09 am
Contact:

[101] Presentation error

Post by StepLg »

Where? I tried to find... But it wasn't successful :(

Code: Select all

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <string.h>

#define NMax 25

struct block
{
  int N;
  block *next, *prev;
};  

// this function printing the world
void PrintWorld(block **world, int N)
{
  block *cur;
  int i;
  for (i=0; i<N-1; ++i)
  {
    printf("%2d:", i);
    cur = world[i];
    while(cur!=NULL)
    {
      printf(" %d", cur->N);
      cur = cur->next;
    }
    printf("\n");  
  }
  // printing the last position of the world
  printf("%2d:", N-1);
  cur = world[N-1];
  while (cur!=NULL)
  {
    printf(" %d", cur->N);
    cur = cur->next;
  }  
  return;
}  

/* 
   this functions puts block Pil and all
   blocks that are stacked on top of block
   Pil to their initial positions
*/
void InitPil(block *pil, block **world)
{
  block *cur;
  if(pil->prev!=NULL)
  {
    pil->prev->next = NULL;
    pil->prev = NULL;
    world[pil->N] = pil;
  }
  cur = pil;
  while (cur->next!=NULL)
  {
    cur = cur->next;
    cur->prev->next = NULL;
    cur->prev = NULL;
    world[cur->N] = cur;
  }
  return;
}

int main()
{
#ifndef ONLINE_JUDGE 
  close(0); open("solve.in", O_RDONLY);
  close(1); open("solve.out", O_WRONLY|O_CREAT|O_TRUNC, 0600);
#endif 

  int N, a, b, i, flag;
  char comm[5], type[5];
  block *world[NMax], positions[NMax], *cur;
  scanf("%d", &N);
  for (i=0; i<N; ++i)
  {
    positions[i].N = i;
    positions[i].prev = positions[i].next = NULL;
    world[i] = positions+i;
  }  
  while (scanf("%s %d %s %d", comm, &a, type, &b)==4)
  {
    if (!strcmp(comm, "quit")) break;
    /* checking the accuracy of input command */
    flag = 0;
    cur = &positions[a];
    while ((cur->next!=NULL)&&(flag==0))
    {
      cur = cur->next;
      if (cur->N==b) flag = 1;
    }
    cur = &positions[b];
    while ((cur->next!=NULL)&&(flag==0))
    {
      cur = cur->next;
      if (cur->N==a) flag = 1;
    }
    
    if ((!flag)&&(a!=b)&&(a<N)&&(b<N))
    {
      /* parsing command */
      if (!strcmp(comm, "move"))
        if (!strcmp(type, "onto"))
        {
          InitPil(&positions[a], world);
          if (positions[b].next!=NULL) InitPil(positions[b].next, world);
          positions[b].next = &positions[a];
          positions[a].prev = &positions[b];
          world[a] = NULL;
        }
        else /* then it is "move a over b" */
        {
          InitPil(&positions[a], world);
          cur = &positions[b];
          while(cur->next!=NULL) cur = cur->next;
          cur->next = &positions[a];
          positions[a].prev = cur;
          world[a] = NULL;
        }
      else /* then it is "pile a .... b */
        if (!strcmp(type, "onto"))
        {
          if (positions[b].next!=NULL) InitPil(positions[b].next, world);
          positions[b].next = &positions[a];
          if(positions[a].prev==NULL) world[a] = NULL;
          else positions[a].prev->next = NULL;
          positions[a].prev = &positions[b];
        }
        else /* then it is "pile a over b" */
        {
          cur = &positions[b];
          while (cur->next!=NULL) cur = cur->next;
          cur->next = &positions[a];
          if(positions[a].prev==NULL) world[a] = NULL;
          else positions[a].prev->next = NULL;
          positions[a].prev = cur;
        }
      }
  }
  
  // printing the world
  PrintWorld(world, N);
  return 0;
}
mamun
A great helper
Posts: 286
Joined: Mon Oct 03, 2005 1:54 pm
Location: Bangladesh
Contact:

Post by mamun »

Looks like you have to print a new line at the end of last line of output.
StepLg
New poster
Posts: 6
Joined: Wed Dec 28, 2005 10:09 am
Contact:

Post by StepLg »

no, there isn't a new line after the last position of the world. Specially for this I process it separately - not in the general circle.
chunyi81
A great helper
Posts: 293
Joined: Sat Jun 21, 2003 4:19 am
Location: Singapore

Post by chunyi81 »

What mamun means is this:

Code: Select all

  // printing the last position of the world 
  printf("%2d:", N-1); 
  cur = world[N-1]; 
  while (cur!=NULL) 
  { 
    printf(" %d", cur->N); 
    cur = cur->next; 
  }  
  printf("\n");//Add this in
At the last line of output you also need a newline or you will get PE.

Example: (\n means newline)

Input

Code: Select all

2
move 1 onto 0
quit
Correct output is

Code: Select all

 0: 0 1\n
 1:\n
But your program outputs

Code: Select all

 0: 0 1\n
 1:
StepLg
New poster
Posts: 6
Joined: Wed Dec 28, 2005 10:09 am
Contact:

Post by StepLg »

The problem: output format.
There should be one line of output for each block position (i.e., n lines of output where n is the integer on the first line of input).
Because of this, i thought, that there shouldn't be the '\n' symbol after the last position.

But you were right, when recommend me to output the '\n' symbol at the end. And more - output format for position number should be "%d:", not "%2d".
beloni
Learning poster
Posts: 66
Joined: Thu Jan 05, 2006 1:41 pm
Location: Pelotas, RS, Brazil

101 - Why runtime error ?

Post by beloni »

this is my code:
(the comments are in portuguese language)


#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>

#define MAX 30


class Strips
{
private:
int matrix[MAX][MAX];
int position[MAX];
int top[MAX];
int size;

public:
Strips(int init_size);
void moveOnto(int a, int b);
void moveOver(int a, int b);
void pileOnto(int a, int b);
void pileOver(int a, int b);
void print();
};

Strips::Strips(int init_size)
{
size = init_size;
for(int w = 0; w < size; w++)
{
matrix[w][0] = w;
position[w] = w;
top[w] = 0;
}
}

void Strips::moveOnto(int a, int b)
{
int A, B;
int posa = position[a];
int posb = position;
// std::cout << "moveOnto" << std::endl;
if(a != b && posa != posb)
{
while(true)
{
A = matrix[posa][top[posa]];
top[posa]--;

if(A == a) break;
else // ajeitar a situa
IRA
Learning poster
Posts: 82
Joined: Sat Jan 07, 2006 6:52 am

101 RE

Post by IRA »

Code: Select all

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;
vector <int>v[50];
vector <int>t;
int    block_pos[50];
vector <int>::iterator it;

void box_print(int n)
{
	int i;
	for(i=0;i<n;i++)
	{
		printf("%d:",i);
		for(it=v[i].begin();it!=v[i].end();it++)
			printf(" %d",*it);
		
		printf("\n");
	}
}

void move_onto(int a,int b)
{
	if(block_pos[a]!=block_pos[b])
	{
		int temp;
		//printf("[1]\n");
		while( a!=(temp=v[block_pos[a]].back()) )
		{
		//	printf("[2]\n");
			v[temp].push_back(temp);
			v[block_pos[a]].pop_back();
			block_pos[temp]=temp;
		}
		while( b!=(temp=v[block_pos[b]].back()) )
		{
		//	printf("[3]\n");
			v[temp].push_back(temp);
			v[block_pos[b]].pop_back();
			block_pos[temp]=temp;
		}
		//printf("[4]\n");
		//將a搬到b
		v[block_pos[b]].push_back(a);
		//排除a
		v[block_pos[a]].pop_back();
		//a和b的位置一樣
		block_pos[a]=block_pos[b];
	}
}

void move_over(int a,int b)
{
	if(block_pos[a]!=block_pos[b])
	{
		int temp;
		//printf("[5]\n");
		while( a!=(temp=v[block_pos[a]].back()) )
		{
		//	printf("[6]\n");
			v[temp].push_back(temp);
			v[block_pos[a]].pop_back();
			block_pos[temp]=temp;
		}
		//printf("[7]\n");
		//將a搬到b
		v[block_pos[b]].push_back(a);
		//排除a
		v[block_pos[a]].pop_back();
		//a和b的位置一樣
		block_pos[a]=block_pos[b];
	}
}

void pile_onto(int a,int b)
{
	if(block_pos[a]!=block_pos[b])
	{
		int temp;
		//printf("[8]\n");
		//b上的積木搬回原位
		while( b!=(temp=v[block_pos[b]].back()) )
		{
			//printf("[9]\n");
			v[temp].push_back(temp);
			v[block_pos[b]].pop_back();
			block_pos[temp]=temp;
		}
		//printf("[10]\n");
		t.clear();
		while( a!=(temp=v[block_pos[a]].back()) )
		{
			t.push_back(temp);
			v[block_pos[a]].pop_back();
			block_pos[temp]=b;
		}
		//將a搬到b
		v[block_pos[b]].push_back(a);
		//排除a
		v[block_pos[a]].pop_back();
		//a和b的位置一樣
		block_pos[a]=block_pos[b];
		//
		for(it=t.begin();it!=t.end();it++)
			v[block_pos[b]].push_back(*it);
	}
}

void pile_over(int a,int b)
{
	if(block_pos[a]!=block_pos[b])
	{
		int temp;

		t.clear();
		while( a!=(temp=v[block_pos[a]].back()) )
		{
			t.push_back(temp);
			v[block_pos[a]].pop_back();
			block_pos[temp]=b;
		}
		//將a搬到b
		v[block_pos[b]].push_back(a);
		//排除a
		v[block_pos[a]].pop_back();
		//a和b的位置一樣
		block_pos[a]=block_pos[b];
		//
		for(it=t.begin();it!=t.end();it++)
			v[block_pos[b]].push_back(*it);
	}
}

void ini(int n)
{
	int i;
	for(i=0;i<n;i++)
	{
		block_pos[i]=i;
		v[i].clear();
		v[i].push_back(i);
	}
}


int main()
{

	int n,a,b;
	char sen1[10];
	char sen2[10];
	//printf("%d",v[0].size());

	while(scanf("%d",&n)==1)
	{
		ini(n);
		//box_print(n);
		while(1)
		{
			scanf("%s",sen1);
			if(!strcmp(sen1,"quit"))
				break;
			scanf("%d %s %d",&a,sen2,&b);
			if( a<n && b<n )
			if(!strcmp(sen1,"move")&&!strcmp(sen2,"onto"))
				move_onto(a,b);
			else if(!strcmp(sen1,"move")&&!strcmp(sen2,"over"))
				move_over(a,b);
			else if(!strcmp(sen1,"pile")&&!strcmp(sen2,"onto"))
				pile_onto(a,b);
			else
				pile_over(a,b);	
		}
		//printf("==================\n");
		box_print(n);
	}



	return 0;
}
I got RE!
Who can help me to find the problem?
Thanks in advance!
chunyi81
A great helper
Posts: 293
Joined: Sat Jun 21, 2003 4:19 am
Location: Singapore

Post by chunyi81 »

Did you run your code with the sample input. Your code does not even give the right output for the sample input.

I think you forgot this sentence in the problem specifications:
Any command in which a = b or in which a and b are in the same stack of blocks is an illegal command. All illegal commands should be ignored and should have no affect on the configuration of blocks.
IRA
Learning poster
Posts: 82
Joined: Sat Jan 07, 2006 6:52 am

Post by IRA »

chunyi81 wrote:Did you run your code with the sample input. Your code does not even give the right output for the sample input.

I think you forgot this sentence in the problem specifications:
Any command in which a = b or in which a and b are in the same stack of blocks is an illegal command. All illegal commands should be ignored and should have no affect on the configuration of blocks.
I do it!...But I still get RE!
tan_Yui
Experienced poster
Posts: 155
Joined: Sat Jul 10, 2004 12:41 am

Post by tan_Yui »

IRA wrote:
chunyi81 wrote:Did you run your code with the sample input. Your code does not even give the right output for the sample input.
I do it!...But I still get RE!
Try again.. and check your output for the sample input, carefully.

And, this problem is handled only one case of input.
You don't need to check to multiple input. :wink:

Best regards.
Jim
New poster
Posts: 2
Joined: Mon Feb 13, 2006 7:05 am

101 Problem

Post by Jim »

Ok I give up , I've tried sample input and get correct answer, and as far as I can tell trapped illegal/invalid inputs.

Can some one check this code out and tell me why I keep getting Wrong Answer?

Jim
javascript:emoticon(':(')

program v1_001;

uses SysUtils;
type
TCommandTypes = (ctmoveonto, ctmoveover, ctpileover, ctpileonto, ctquit, ctinvalid);
var
BlockStack : array[0..24,0..24] of integer;
MaxBlocks : Integer;
SourceBlock,
DestinationBlock : Integer;

function ParseLine(lstr : String) : TCommandTypes;
var
p1,p2,p3,p4 : String;
l,
idx : Integer;
res : TCommandTypes;
begin
p1 := '';
p2 := '';
p3 := '';
p4 := '';
idx := 1;
l := length(lstr);
while (idx <= l) and (lstr[idx] <> ' ') do
begin
p1 := p1 + lstr[idx];
idx := idx + 1;
end;
if p1 = 'quit' then
begin
ParseLine := ctquit;
exit;
end;
idx := idx + 1;

while (idx <= l) and (lstr[idx] <> ' ') do
begin
p2 := p2 + lstr[idx];
idx := idx + 1;
end;
idx := idx + 1;
while (idx <= l) and (lstr[idx] <> ' ') do
begin
p3 := p3 + lstr[idx];
idx := idx + 1;
end;
idx := idx + 1;
while (idx <= l) and (lstr[idx] <> ' ') do
begin
p4 := p4 + lstr[idx];
idx := idx + 1;
end;

res := ctInvalid;
if p1 = 'move' then
begin
if p3 = 'over' then
res := ctmoveover
else if p3 = 'onto' then
res := ctmoveonto;
end
else if p1 = 'pile' then
begin
if p3 = 'over' then
res := ctpileover
else if p3 = 'onto' then
res := ctpileonto;
end;

if res <> ctInvalid then
begin
SourceBlock := StrToInt(p2);
DestinationBlock := StrToInt(p4);
if (SourceBlock > MaxBlocks) or (DestinationBlock > MaxBlocks) then
res := ctInvalid;
if (SourceBlock < 0) or (DestinationBlock < 0 ) then
res := ctInvalid;
end;
ParseLine := res;
end;

procedure GetLocation(var loca,locb,posa,posb : Integer;source,destination : Integer);
var
b,
i,j : Integer;
begin
loca := -1;
if Source = Destination then
exit;

locb := -1;
for i:= 0 to MaxBlocks do
begin
for j:= 0 to MaxBLocks do
begin
b := BlockStack[i,j];
if b = -1 then
break; {empty so dont look}
if b = source then
begin
loca := i;
posa := j;
end
else if b = destination then
begin
locb := i;
posb := j;
end;
end;
end;
if loca = locb then
loca := -1; {same stack - dont allow}
end;

procedure MoveOnto;
var
i, b,
loca,posa,
locb,posb : Integer;

begin
GetLocation(loca,locb,posa,posb,SourceBlock,DestinationBlock);
if loca = -1 then
exit;

{move a onto b
where a and b are block numbers,
puts block a onto block b
after returning any blocks that are stacked on top of blocks a and b to their initial positions.
}
{shunt off the ones ontop of a}
for i:= posa+1 to MaxBlocks do
begin
b := BlockStack[loca,i];
if b = -1 then
break;
{ok this one has to go back home}
BlockStack[b,0] := b;
BlockStack[loca,i] := -1;
end;
{shunt off the ones ontop of b}
for i:= posb+1 to MaxBlocks do
begin
b := BlockStack[locb,i];
if b = -1 then
break;
{ok this one has to go back home}
BlockStack[b,0] := b;
BlockStack[locb,i] := -1;
end;
{now move a onto b}
BlockStack[locb,posb+1] := SourceBlock;
BlockStack[loca,posa] := -1;
end;

procedure MoveOver;
var
i, b,
loca,posa,
locb,posb : Integer;

begin
GetLocation(loca,locb,posa,posb,SourceBlock,DestinationBlock);
if loca = -1 then
exit;
{
# move a over b
where a and b are block numbers,
puts block a onto the top of the stack containing block b,
after returning any blocks that are stacked on top of block a to their initial positions.
}
{shunt off the ones ontop of a}
for i:= posa+1 to MaxBlocks do
begin
b := BlockStack[loca,i];
if b = -1 then
break;
{ok this one has to go back home}
BlockStack[b,0] := b;
BlockStack[loca,i] := -1;
end;
{now move a onto b}
{find position to a onto }
for i:= posb+1 to MaxBlocks do
begin
b := BlockStack[locb,i];
if b = -1 then
begin
posb := i;
break;
end;
end;
BlockStack[locb,posb] := SourceBlock;
BlockStack[loca,posa] := -1;
end;

procedure PileOnto;
var
i, b,
loca,posa,
locb,posb : Integer;
begin
{
# pile a onto b
where a and b are block numbers,
moves the pile of blocks consisting of block a,
and any blocks that are stacked above block a, onto block b.
All blocks on top of block b are moved to their initial positions prior to the pile taking place.
The blocks stacked above block a retain their order when moved.
}
GetLocation(loca,locb,posa,posb,SourceBlock,DestinationBlock);
if loca = -1 then
exit;
{shunt off the ones ontop of b}
for i:= posb+1 to MaxBlocks do
begin
b := BlockStack[locb,i];
if b = -1 then
break;
{ok this one has to go back home}
BlockStack[b,0] := b;
BlockStack[locb,i] := -1;
end;

{move a and those above it}
for i:= posa to MaxBlocks do
begin
posb := posb + 1;
BlockStack[locb,posb] := BlockStack[loca,i];
BlockStack[loca,i] := -1;
end;
end;

procedure PileOver;
var
i, b,
loca,posa,
locb,posb : Integer;
begin
{
# pile a over b
where a and b are block numbers,
puts the pile of blocks consisting of block a,
and any blocks that are stacked above block a,
onto the top of the stack containing block b.
The blocks stacked above block a retain their original order when moved.
}
GetLocation(loca,locb,posa,posb,SourceBlock,DestinationBlock);
if loca = -1 then
exit;

{ now find open spot on b }
for i:= posb+1 to MaxBlocks do
begin
if BlockStack[locb,i] = -1 then
begin
posb := i;
break;
end;
end;
{move a and those above it}
for i:= posa to MaxBlocks do
begin
BlockStack[locb,posb] := BlockStack[loca,i];
BlockStack[loca,i] := -1;
posb := posb + 1;
end;

end;

procedure OutPutBlocks;
var
i,j : Integer;
lstr : String;
begin
for i:= 0 to MaxBLocks do
begin
lstr := IntToStr(i)+':';
for j:= 0 to MaxBLocks do
begin
if BlockStack[i,j] = -1 then
break;
lstr := lstr + ' '+ IntToStr(BlockStack[i,j]);
end;
WriteLn(lstr);
end;
end;

var
ps : TCommandTypes;
i,j : Integer;
lstr : String;
begin

{set up the storage array }
ReadLn(lstr);
MaxBLocks := StrToInt(lstr)-1;
for i:= 0 to MaxBLocks do
begin
for j:= 1 to MaxBLocks do
BlockStack[i,j] := -1;{empty}
BlockStack[i,0] := i; {orig position}
end;

while NOT Eof(input) do
begin
ReadLn(lstr);
ps := ParseLine(lstr);
case ps of
ctmoveonto : MoveOnto;
ctmoveover : MoveOver;
ctpileonto : PileOnto;
ctpileover : PileOver;
ctquit : break;
end;
i := i + 1;
end;
OutputBLocks;
end.
sclo
Guru
Posts: 519
Joined: Mon Jan 23, 2006 10:45 pm
Location: Vancouver, BC, Canada
Contact:

Post by sclo »

Your code is much longer than it need be. It's too much for me to debug, maybe try to rewrite the code, you might be able to get rid of the bug.
Jim
New poster
Posts: 2
Joined: Mon Feb 13, 2006 7:05 am

Post by Jim »

It may be long, but if anyone has written a Pascal solver that was accepted, then they could compare the output. Or even compare the output from a C program. I suspect it's something trivial like a space or something, rather than getting the "wrong" output. I've checked back in the forums and every sample input has generated the output that is expected. I don't think the program is incorrect.

I guess this puts paid my idea of solving the problems in order.
IRA
Learning poster
Posts: 82
Joined: Sat Jan 07, 2006 6:52 am

Post by IRA »

I still got RE.....
Does the quation have special input data?
My friend also got RE.....
Darko
Guru
Posts: 580
Joined: Fri Nov 11, 2005 9:34 am
Location: Calgary, Canada

Post by Darko »

I have the same trouble with my Java code, but I get WA (it must be RE, because it is WA in 0.006, and there is no way it can run that fast - RE being reported as WA with Java is usual stuff).

I was really paranoid, checking for empy lines, checking for right format (although it says that commands will be in the right format), but I really have no idea what is wrong.

I, too, checked all the available input on the boards. (and I think they covered all the tricky cases)

Btw, I recoded it from scratch, hoping that I made some silly mistake, but same thing... I have no idea what I could be missing.

Darko
Post Reply

Return to “Volume 1 (100-199)”