Posted: Tue Jan 18, 2005 5:12 am
Thanks a lot! I finally work it out! I think my pile_onto()function has some small mistakes.
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STACKS 25
/* Function Prototypes */
void initBlockWorld( int stacks[MAX_STACKS][MAX_STACKS], int numStacks );
int findBlock( int stacks[MAX_STACKS][MAX_STACKS], int numStacks, int target );
void printBlockWorld( int stacks[MAX_STACKS][MAX_STACKS], int numStacks );
void returnBlocksOnTop( int stacks[MAX_STACKS][MAX_STACKS], int numStacks, int target, int targetStack );
void pileBlocks( int stacks[MAX_STACKS][MAX_STACKS], int numStacks, int target, int src, int dest );
main() {
int stacks[MAX_STACKS][MAX_STACKS]; /* Stacks of blocks. Blocks represented by integers, non-blocks by -1 */
int numStacks; /* Number of stacks, number of blocks is the same */
char command[25]; /* Command to robot (move/pile, onto/over) */
int srcBlock, destBlock; /* Block to move/pile, onto/over */
int srcStack, destStack; /* Stack of the src/dest blocks */
char cmd1[6], cmd2[6]; /* cmd1 = move/pile, cmd2 = onto/over */
char temp[6];
/* Get number of stacks and initialize the block world */
scanf("%d", &numStacks);
initBlockWorld( stacks, numStacks );
/* Get first command */
fflush(stdin);
gets(command);
/* Execute all commands from input until "quit" is input */
while( strcmp(command, "quit") != 0 ) {
/* Extract tokens from command string */
strcpy( cmd1, strtok( command, " " ) );
strcpy( temp, strtok( NULL, " " ) );
sscanf( temp, "%d", &srcBlock );
strcpy( cmd2, strtok( NULL, " " ) );
strcpy( temp, strtok( NULL, "\n" ) );
sscanf( temp, "%d", &destBlock );
/* Find stack of the source and destination blocks */
srcStack = findBlock( stacks, numStacks, srcBlock );
destStack = findBlock( stacks, numStacks, destBlock );
/* Make sure srcStack isn't the same as destStack, if it is then ignore command */
if( srcStack != destStack ) {
/* If cmd1 is move, return blocks on top of source block to original stacks */
if( strcmp( cmd1, "move" ) == 0 ) {
returnBlocksOnTop( stacks, numStacks, srcBlock, srcStack );
}
/* If cmd2 is onto, return blocks on top of dest block to original stacks */
if( strcmp( cmd2, "onto" ) == 0 ) {
returnBlocksOnTop( stacks, numStacks, destBlock, destStack );
}
/* Pile from src to dest */
pileBlocks( stacks, numStacks, srcBlock, srcStack, destStack );
}
/* Get next command */
fflush(stdin);
gets(command);
}
/* Print block world */
printBlockWorld( stacks, numStacks );
}
void initBlockWorld( int stacks[MAX_STACKS][MAX_STACKS], int numStacks ) {
int i, j;
/* Set all entries to -1 */
for( i = 0; i < numStacks; i++ ) {
for( j = 0; j < numStacks; j++ ) {
stacks[i][j] = -1;
}
}
/* Place initial blocks */
for( i = 0; i < numStacks; i++ ) {
stacks[i][0] = i;
}
}
/* Returns which stack the target block is in */
int findBlock( int stacks[MAX_STACKS][MAX_STACKS], int numStacks, int target ) {
int i, j;
for( i = 0; i < numStacks; i++ ) {
for( j = 0; j < numStacks; j++ ) {
if( target == stacks[i][j] ) {
return i;
}
}
}
}
void printBlockWorld( int stacks[MAX_STACKS][MAX_STACKS], int numStacks ) {
int i, j;
/* Print stack#: block1, block2, etc... */
for( i = 0; i < numStacks; i++ ) {
printf("%d:", i);
for( j = 0; j < numStacks; j++ ) {
if( stacks[i][j] != -1 ) {
printf(" %d", stacks[i][j]);
}
}
if( i < numStacks-1 ) {
printf("\n");
}
}
}
/* Returns all blocks on top of target block back to orginal stack. Returns the location of the target block in its stack */
void returnBlocksOnTop( int stacks[MAX_STACKS][MAX_STACKS], int numStacks, int target, int targetStack ) {
int i, loc;
/* Find location of target block within stack */
for( i = 0; i < numStacks; i++ ) {
if( stacks[targetStack][i] == target ) {
loc = i;
}
}
/* Clear blocks off the top of target */
/* Start from top of stack, work way down to target. Use pile to put the block onto its original stack */
for( i = numStacks-1; i > loc; i-- ) {
if( stacks[targetStack][i] != -1 ) {
pileBlocks( stacks, numStacks, stacks[targetStack][i], targetStack, stacks[targetStack][i] );
}
}
}
/* Piles all blocks starting with target block in source stack to destination stack */
void pileBlocks( int stacks[MAX_STACKS][MAX_STACKS], int numStacks, int target, int src, int dest ) {
int i, srcLoc, destLoc;
if( src != dest ) {
/* Get srcLoc, destLoc - the locations to start swapping */
for( i = 0; i < numStacks; i++ ) {
if( stacks[src][i] == target ) {
srcLoc = i;
break;
}
}
for( i = 0; i < numStacks; i++ ) {
if( stacks[dest][i] == -1 ) {
destLoc = i;
break;
}
}
/* Swap all blocks from src stack with non-blocks (-1) from dest stack starting at the srcLoc and destLoc */
while( stacks[src][srcLoc] != -1 && srcLoc < numStacks ) {
stacks[dest][destLoc] = stacks[src][srcLoc];
stacks[src][srcLoc] = -1;
srcLoc++;
destLoc++;
}
}
else {
/* Error! Can't have src == dest */
}
}
Code: Select all
#include<stdio.h>
#include<string.h>
int block_number;
int pos;
struct b
{
int top;
int stack[26];
}block[26];
void init()
{
int i;
for(i=0;i<=block_number;i++)
{
block[i].top = 0;
block[i].stack[0]=i;
}
}
int search(int number)
{
int i;
for(i=0;i<block_number;i++)
{
for(pos=0;pos<=block[i].top;pos++)
if(block[i].stack[pos] == number)
return i;
}
return 0;
}
int check(int a, int b)
{
int a_stack, b_stack;
a_stack=search(a);
b_stack=search(b);
if(a_stack==b_stack)
return 0;
return 1;
}
int pop(int stack_number)
{
int tmp;
tmp= block[stack_number].stack[block[stack_number].top];
block[stack_number].top--;
return tmp;
}
void push(int stack_number, int number)
{
block[stack_number].top ++;
block[stack_number].stack[block[stack_number].top]=number;
}
void release(int stack_number, int item)
{
int tmp,i;
for(i=block[stack_number].top;;i--)
{
tmp=pop(stack_number);
if(tmp==item)
{
block[stack_number].top++;
break;
}
push(tmp,tmp);
block[stack_number].top--;
}
}
void move_onto(int a, int b)
{
int a_stack,b_stack;
a_stack=search(a);
release(a_stack,a);
b_stack=search(b);
release(b_stack,b);
push(b_stack,pop(a_stack));
}
void move_over(int a, int b)
{
int a_stack, b_stack;
a_stack=search(a);
release(a_stack,a);
b_stack=search(b);
push(b_stack,pop(a_stack));
}
void pile_onto(int a, int b)
{
int a_stack, b_stack;
int a_pos,i;
a_stack=search(a);
a_pos=pos;
b_stack=search(b);
release(b_stack,b);
push(b_stack,a);
for(i=a_pos;i<=block[a_stack].top;i++)
{
block[b_stack].stack[block[b_stack].top++ ]=block[a_stack].stack[i];
}
block[a_stack].top = a_pos-1;
block[b_stack].top--;
}
void pile_over(int a, int b)
{
int a_stack, b_stack;
int a_pos,i;
a_stack=search(a);
a_pos=pos;
b_stack=search(b);
push(b_stack,a);
for(i=a_pos;i<=block[a_stack].top;i++)
{
block[b_stack].stack[block[b_stack].top++ ]=block[a_stack].stack[i];
}
block[a_stack].top = a_pos-1;
block[b_stack].top--;
}
int main()
{
char string[50],option[50];
int a,b,i,j;
scanf("%d",&block_number);
init();
while(1)
{
scanf("%s", string);
if(strcmp(string,"quit")==0)
break;
scanf("%d %s %d",&a,option,&b);
if(check(a,b)==1)
{
if(strcmp(string,"move")==0 && strcmp(option,"onto")==0)
{
move_onto(a,b);
}
else if(strcmp(string,"move")==0 && strcmp(option,"over")==0)
{
move_over(a,b);
}
else if(strcmp(string,"pile")==0 && strcmp(option,"onto")==0)
{
pile_onto(a,b);
}
else if(strcmp(string,"pile")==0 && strcmp(option,"over")==0)
{
pile_over(a,b);
}
}
}
for(i=0;i<block_number;i++)
{
printf("%d: ",i);
for(j=0;j<=block[i].top;j++)
printf("%d ",block[i].stack[j]);
printf("\n");
}
return 0;
}
Code: Select all
19
move 1 onto 0
move 0 onto 1
move 0 onto 2
move 2 onto 1
move 4 over 5
move 7 onto 8
move 9 onto 7
move 7 over 9
move 9 over 7
move 11 over 10
move 12 over 10
move 13 over 10
move 14 over 10
move 16 over 15
move 17 over 15
move 18 over 15
move 16 onto 14
pile 17 onto 12
move 15 over 10
pile 17 onto 14
pile 15 over 7
pile 6 over 5
pile 3 onto 9
quit
Code: Select all
Code:
19
move 1 onto 0
move 0 onto 1
move 0 onto 2
move 2 onto 1
move 4 over 5
move 7 onto 8
move 9 onto 7
move 7 over 9
move 9 over 7
move 11 over 10
move 12 over 10
move 13 over 10
move 14 over 10
move 16 over 15
move 17 over 15
move 18 over 15
move 16 onto 14
pile 17 onto 12
move 15 over 10
pile 17 onto 14
pile 15 over 7
pile 6 over 5
pile 3 onto 9
quit
Ouput:
Code:
0:0
1:1 2
2:
3:
4:
5:5 4 6
6:
7:
8:8 7 9 3
9:
10:10 11 12
11:
12:
13:13
14:14 17
15:15
16:16
17:
18:18
Code: Select all
#include <iostream>
#include <string>
using namespace std;
int WS= 0; //worldsize
short int BW[25][25]; //blockworld
short int BL[25][2]; //blockworld
string P1, P2; //parameter 1, parameter 2
int A, B; //block A, block B
const int X= 0, Y= 1;
void robotArm(string P1, int A, string P2, int B);
void printWorld();
void initializeWorld();
bool anyBlocksAbove(int A);
void moveBlock(int A, int x, int y);
void moveBlocksAbove(int x, int y, int DestX);
int findFreeX(int avoidX[], int Elements);
int findFreeY(int x);
int getX(int A);
int getY(int A);
int main() {
cin >> WS;
initializeWorld();
do {
cin >> P1;
if (P1 == "quit") {
printWorld();
break;
} else if (P1 == "print") {
printWorld();
} else if (P1 == "init") {
initializeWorld();
printWorld();
} else {
cin >> A;
cin >> P2;
cin >> B;
if (BL[A][X] != BL[B][X]) {
robotArm(P1, A, P2, B);
//printWorld();
}
}
} while (1);
return 0;
}
void robotArm(string P1, int A, string P2, int B) {
int srcX= getX(A);
int destX= getX(B);
if (P1 == "move") {
if (P2 == "over") {
if (! anyBlocksAbove(A)) {
moveBlock(A, destX, findFreeY(getX(B)));
} else {
int avoidX[]= { srcX, destX };
int tmpX= findFreeX(avoidX, sizeof(avoidX)/4);
int tmpY= findFreeY(tmpX) -1;
moveBlocksAbove(srcX, getY(A), tmpX);
moveBlock(A, destX, findFreeY(B));
moveBlocksAbove(tmpX, tmpY, srcX);
}
} else {
if (! anyBlocksAbove(A) && ! anyBlocksAbove(B)) {
moveBlock(A, destX, findFreeY(getX(B)));
} else if (anyBlocksAbove(A) && ! anyBlocksAbove(B)) {
int avoidX[]= { srcX, destX };
int tmpX= findFreeX(avoidX, sizeof(avoidX)/4);
int tmpY= findFreeY(tmpX) -1;
moveBlocksAbove(srcX, getY(A), tmpX);
moveBlock(A, destX, findFreeY(getX(B)));
moveBlocksAbove(tmpX, tmpY, srcX);
} else if (! anyBlocksAbove(A) && anyBlocksAbove(B)) {
int avoidX[]= { srcX, destX };
int tmpX= findFreeX(avoidX, sizeof(avoidX)/4);
int tmpY= findFreeY(tmpX) -1;
moveBlocksAbove(destX, getY(B), tmpX);
moveBlock(A, destX, findFreeY(getX(B)));
moveBlocksAbove(tmpX, tmpY, destX);
} else if (anyBlocksAbove(A) && anyBlocksAbove(B)) {
//A block
int avoidX1[]= { srcX, destX };
int tmpX1= findFreeX(avoidX1, sizeof(avoidX1)/4);
int tmpY1= findFreeY(tmpX1) -1;
moveBlocksAbove(srcX, getY(A), tmpX1);
//
//B block
int avoidX2[]= { srcX, destX, tmpX1 };
int tmpX2= findFreeX(avoidX2, sizeof(avoidX2)/4);
int tmpY2= findFreeY(tmpX2) -1;
moveBlocksAbove(destX, getY(B), tmpX2);
//
moveBlock(A, destX, findFreeY(getX(B)));
moveBlocksAbove(tmpX1, tmpY1, srcX);
moveBlocksAbove(tmpX2, tmpY2, destX);
}
}
} else {
if (P2 == "over") {
if (anyBlocksAbove(A)) {
int avoidX[]= { srcX, destX };
int tmpX= findFreeX(avoidX, sizeof(avoidX)/4);
int tmpY= findFreeY(tmpX) -1;
int destY= findFreeY(destX);
moveBlocksAbove(srcX, getY(A), tmpX);
moveBlock(A, destX, destY);
moveBlocksAbove(tmpX, tmpY, destX);
} else {
moveBlock(A, getX(B), findFreeY(getX(B)));
}
} else {
if (! anyBlocksAbove(A) && ! anyBlocksAbove(B)) {
moveBlock(A, getX(B), findFreeY(getX(B)));
} else if (anyBlocksAbove(A) && ! anyBlocksAbove(B)) {
int avoidX[]= { srcX, destX };
int tmpX= findFreeX(avoidX, sizeof(avoidX)/4);
int tmpY= findFreeY(tmpX) -1;
int destY= findFreeY(destX);
moveBlocksAbove(srcX, getY(A), tmpX);
moveBlock(A, destX, destY);
moveBlocksAbove(tmpX, tmpY, destX);
} else if (! anyBlocksAbove(A) && anyBlocksAbove(B)) {
int avoidX1[]= { srcX, destX };
int tmpX1= findFreeX(avoidX1, sizeof(avoidX1)/4);
int tmpY1= findFreeY(tmpX1) -1;
moveBlocksAbove(destX, getY(B), tmpX1);
moveBlock(A, getX(B), findFreeY(getX(B)));
moveBlocksAbove(tmpX1, tmpY1, destX);
} else if (anyBlocksAbove(A) && anyBlocksAbove(B)) {
int avoidX1[]= { srcX, destX };
int tmpX1= findFreeX(avoidX1, sizeof(avoidX1)/4);
int tmpY1= findFreeY(tmpX1) -1;
moveBlocksAbove(destX, getY(B), tmpX1);
//pile A move
int avoidX2[]= { srcX, destX, tmpX1 };
int tmpX2= findFreeX(avoidX2, sizeof(avoidX2)/4);
int tmpY2= findFreeY(tmpX2) -1;
moveBlocksAbove(srcX, getY(A), tmpX2);
moveBlock(A, destX, findFreeY(getX(B)));
moveBlocksAbove(tmpX2, tmpY2, destX);
//
moveBlocksAbove(tmpX1, tmpY1, destX);
}
}
}
}
void moveBlock(int A, int x, int y) {
BW[ getX(A) ][ getY(A) ]= -1;
BW[x][y]= A;
BL[A][X]= x;
BL[A][Y]= y;
}
bool anyBlocksAbove(int A) {
if (getY(A) != WS-1) {
if (BW[ getX(A) ][ getY(A)+1 ] != -1) {
return true;
}
}
return false;
}
void moveBlocksAbove(int x, int y, int destX) {
int srcY= findFreeY(x)-1;
int destY= findFreeY(destX);
for (srcY; srcY>y; srcY--) {
moveBlock(BW[x][srcY], destX, destY);
destY++;
}
}
int findFreeX(int avoidX[], int Elements) {
int out= 0;
bool Okay= true;
for (out; out<WS; out++) {
for (int j= 0; j<Elements; j++) {
if (out == avoidX[j]) {
Okay= false;
break;
}
}
if (Okay == true) { break; }
Okay= true;
}
return out;
}
int findFreeY(int x) {
int y= 0;
for (y; y<WS; y++) {
if (BW[x][y] == -1) { break; }
}
return y;
}
void printWorld() {
for (int x= 0; x<WS; x++) {
cout << x << ":";
for (int y= 0; y<WS; y++) {
if (BW[x][y] != -1) {
cout << " " << BW[x][y];
}
}
cout << endl;
}
}
void initializeWorld() {
for (int x= 0; x<WS; x++) {
BW[x][0]= x;
for (int y= 1; y<WS; y++) {
BW[x][y]= -1;
}
BL[x][X]= x;
BL[x][Y]= 0;
}
}
int getX(int A) {
return BL[A][0];
}
int getY(int A) {
return BL[A][1];
}
Hope this helps:i seem not to understand this problem correctly.
I got AC! Thank you for your assistance!teni_teni wrote:Hope this helps:i seem not to understand this problem correctly.
http://online-judge.uva.es/board/viewto ... hlight=101