`

the blocks problem(uva 101 or poj 1208)

阅读更多

题目描述见:uva 101 or poj 1208

关键在于彻底理解题目中搬积木的几个命令的含义,见具体分析

如果还不能理解题意,那么找一个正确通过的代码,编译并输入测试数据,查看其每一个命令的执行情况。如我的代码中162行注释内容取消后即可显示每一步执行后当前积木的情况)

这个题目似乎没有合适的数据结构,由于插入删除操作较多,所以直接用了链表,并且使用双重指针,差点把自己搞晕。(另外,刚开始写的代码能在poj1208上通过,但不能在uva 101上通过,后来发现是141行中的continue误写成了break。网上也有类似的情况,似乎是因为没有考虑到特殊情况的处理(即两个积木块号相同或者处于同一列时需要忽略该命令))

相关C语言代码:

/* uva 101 or poj 1208 */
/*the Blocks problem */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
  int data;
  struct node *prev;
  struct node *next;
};
typedef struct node *pBlock;
static void CreateHeader(pBlock *ppBlk)
{
  pBlock newBlk = malloc(sizeof(*newBlk));
  newBlk -> next = newBlk->prev = NULL;
  (*ppBlk) = newBlk;
}
static void InsertOnFirst(pBlock *ppBlk,  int data)
{
  pBlock newBlk = malloc(sizeof(*newBlk));
  newBlk -> data = data;
  newBlk -> next = NULL;
  newBlk -> prev = *ppBlk;
  (*ppBlk)->next = newBlk;
}
static int FindBlock(pBlock *ppBlk, int blockNumber, pBlock *ppretBlock)
{
  pBlock tmpBlk = (*ppBlk)->next;
  while(tmpBlk != NULL)
    if(tmpBlk->data == blockNumber)
      {
	*ppretBlock = tmpBlk;
	return 1;
      }
    else
      tmpBlk = tmpBlk->next;
  return 0;
}
static void PopAllFollowBlks(pBlock *ppBTab,pBlock *ppBlk)
{
  pBlock tmpBlk,curBlk = (*ppBlk)->next;
  (*ppBlk)->next = NULL;
  while(curBlk != NULL)
    {
      tmpBlk = curBlk;
      curBlk = curBlk->next;
      ppBTab[tmpBlk->data] ->next = tmpBlk;
      tmpBlk->next = NULL;
      tmpBlk->prev = ppBTab[tmpBlk->data];
    }
}
      
      
static void MoveOnto(pBlock *ppBTab,pBlock *ppSrcBlk, pBlock *ppDstBlk)
{
  PopAllFollowBlks(ppBTab,ppSrcBlk);
  PopAllFollowBlks(ppBTab,ppDstBlk);
  /*pBlock pSrcTmpBlk = pSrcBlk->next,pDstTmpBlk=pDstBlk->next;*/

  (*ppSrcBlk)->prev->next = NULL;
  (*ppSrcBlk) ->next = (*ppDstBlk)->next;
  (*ppSrcBlk)->prev = (*ppDstBlk);
  (*ppDstBlk)->next = (*ppSrcBlk);
}
static void MoveOver(pBlock *ppBTab,pBlock *ppSrcBlk, pBlock *ppDstBlk)
{
  pBlock lastDstBlk = (*ppDstBlk);
  PopAllFollowBlks(ppBTab,ppSrcBlk);
  (*ppSrcBlk)->prev->next = NULL;
  while(lastDstBlk->next != NULL)
    lastDstBlk = lastDstBlk->next;
  (*ppSrcBlk)->next = lastDstBlk->next;
  (*ppSrcBlk)->prev = lastDstBlk;
  lastDstBlk->next = (*ppSrcBlk);
}
static void PileOnto(pBlock *ppBTab,pBlock *ppSrcBlk, pBlock *ppDstBlk)
{

  PopAllFollowBlks(ppBTab,ppDstBlk);
  (*ppSrcBlk)->prev->next = NULL;
  (*ppDstBlk)->next = *ppSrcBlk;
  (*ppSrcBlk)->prev = *ppDstBlk;
}
static void PileOver(pBlock *ppBTab,pBlock *ppSrcBlk, pBlock *ppDstBlk)
{
  pBlock lastDstBlk = (*ppDstBlk);
  (*ppSrcBlk)->prev->next = NULL;
  while(lastDstBlk->next != NULL)
    lastDstBlk = lastDstBlk->next;

  (*ppSrcBlk)->prev = lastDstBlk;
  lastDstBlk->next = (*ppSrcBlk);
}   

static void PrintBlock(pBlock pBlk)
{
  pBlock tmpBlk = (pBlk) -> next;
  while(tmpBlk != NULL)
    {
      printf(" %d",tmpBlk->data);
      tmpBlk = tmpBlk -> next;
    }
  printf("\n");
}
static void PrintBlks(pBlock *ppBlk, int arraysize)
{
  int i;
  for(i = 0; i < arraysize; i++)
    {
      printf("%d:",i);
      PrintBlock(ppBlk[i]);
    }
}
      
int main(void)
{
  int n;
  pBlock *ppBlks,pSrcBlk,pDstBlk;
  char str1[10],str2[10];
  int fstBlkNum,scdBlkNum,i,j;
  int isFound1, isFound2;
  
  scanf("%d",&n);
  getchar();
  ppBlks = malloc(n * sizeof(*ppBlks));
  for(i = 0; i < n; i++)
    {
      CreateHeader(&ppBlks[i]);
      InsertOnFirst(&ppBlks[i],i);
    }
  /*  PrintBlks(ppBlks,n);*/
  while(1)
    {
      scanf("%s",str1);

      if(strcmp(str1,"quit") == 0)
	break;
      scanf("%d %s %d",&fstBlkNum,str2,&scdBlkNum);
      if(fstBlkNum == scdBlkNum)
	continue;
      for(i = 0; i < n; i++)
	{
	  isFound1 = FindBlock(&ppBlks[i],fstBlkNum,&pSrcBlk);
	  if(isFound1)
	    break;
	}
      for(j = 0; j < n; j++)
	{
	  isFound2 = FindBlock(&ppBlks[j],scdBlkNum,&pDstBlk);
	  if(isFound2)
	    break;
	}
      if(i != j && strcmp(str1,"move") == 0 && strcmp(str2,"onto") == 0)
	MoveOnto(ppBlks,&pSrcBlk,&pDstBlk);
      else if(i != j && strcmp(str1,"move") == 0 && strcmp(str2,"over") == 0)
	MoveOver(ppBlks,&pSrcBlk,&pDstBlk);
      else if(i != j && strcmp(str1,"pile") == 0 && strcmp(str2,"onto") == 0)
	PileOnto(ppBlks,&pSrcBlk,&pDstBlk);
      else if(i != j && strcmp(str1,"pile") == 0 && strcmp(str2,"over") == 0)
	PileOver(ppBlks,&pSrcBlk,&pDstBlk);
      /*      PrintBlks(ppBlks,n);*/
    }
  PrintBlks(ppBlks,n); 
  return 0;
}
 

 另外一种方案(使用栈进行操作):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MINSTACKSIZE 30
#define STACKINCREMENT 30
struct stack{
  int capacity;
  int top;
  int *array;
};
typedef struct stack Stack;

Stack *CreateStack()
{
  Stack *pStk = malloc(sizeof(*pStk));
  pStk->array = malloc(MINSTACKSIZE*sizeof(*(pStk->array)));
  if(pStk->array == NULL)
    {
      fprintf(stderr,"error:no space to allocate.\n");
      exit(EXIT_FAILURE);
    }
  else
    {
      pStk->capacity = MINSTACKSIZE;
      pStk->top = 0;
    }
  return pStk;
}

int IsStackEmpty(Stack *pStk)
{
  return pStk->top == 0;
}
int IsStackFull(Stack *pStk)
{
  return pStk->capacity == pStk->top + 1;
}
int Push(Stack *pStk, int data)
{
  if(IsStackFull(pStk))
    {
      pStk->array = realloc(pStk, (pStk->capacity+STACKINCREMENT)*
			    sizeof(*(pStk->array)));
      if(pStk->array == NULL)
	{
	  fprintf(stderr, "error: no space to allocate\n");
	  exit(EXIT_FAILURE);
	}
      else
	{
	  pStk -> capacity += STACKINCREMENT;
	}
    }
  pStk -> array[++(pStk -> top)] = data;
  return 0;
}
int Pop(Stack *pStk)
{
  if(IsStackEmpty(pStk))
    {
      fprintf(stderr,"error: empty stack can pop nothing\n");
      exit(EXIT_FAILURE);
    }
  else
    return pStk->array[(pStk -> top) --] ;
}
int Top(Stack *pStk)
{
  if(IsStackEmpty(pStk))
    {
      fprintf(stderr,"error: empty stack  don't have top element\n");
      exit(EXIT_FAILURE);
    }
  else
    return pStk->array[pStk -> top] ;
}

int Find(Stack *pStk, int data)
{
  int i;
  for(i = 1; i <= pStk->top; i++)
    if(pStk -> array[i] == data)
      break;
  if(i > pStk->top)
    return 0;
  else
    return i;
}

int PopFollowingBack(Stack **ppStkArray, int index, int pos)  
{
  Stack *pCurStk = ppStkArray[index];
  int curData;
  while(pCurStk -> top > pos)
    {
      curData = Pop(pCurStk);
      /*      pTmpStk = ppStkArray[curData];*/
      Push(ppStkArray[curData],curData);
    }
  return 0;
}
int PushCurAndFollowing(Stack **ppStkArray, int srcIndex, int srcPos, 
		     int dstIndex, int dstPos)
{
  int i,srcTop = ppStkArray[srcIndex] -> top;
  for(i = srcPos; i <= srcTop; i++)
    {
      Push(ppStkArray[dstIndex],ppStkArray[srcIndex]->array[i]);
    }
  ppStkArray[srcIndex] -> top -= srcTop - srcPos + 1;
  return 0;
}
int MoveOnto(Stack **ppStkArray,int srcIndex,int srcPos,
	     int dstIndex,int dstPos)
{
  PopFollowingBack(ppStkArray,srcIndex,srcPos);
  PopFollowingBack(ppStkArray,dstIndex,dstPos);
  PushCurAndFollowing(ppStkArray,srcIndex,srcPos,dstIndex,dstPos);
  return 0;
}
int MoveOver(Stack **ppStkArray,int srcIndex,int srcPos,
	     int dstIndex,int dstPos)
{
  PopFollowingBack(ppStkArray,srcIndex,srcPos);
  PushCurAndFollowing(ppStkArray,srcIndex,srcPos,dstIndex,dstPos);
  return 0;
}
int PileOnto(Stack **ppStkArray,int srcIndex,int srcPos,
	     int dstIndex, int dstPos)
{
  PopFollowingBack(ppStkArray,dstIndex,dstPos);
  PushCurAndFollowing(ppStkArray,srcIndex,srcPos,dstIndex,dstPos);
  return 0;
}
int PileOver(Stack **ppStkArray,int srcIndex,int srcPos,
	     int dstIndex,int dstPos)
{
  PushCurAndFollowing(ppStkArray,srcIndex,srcPos,dstIndex,dstPos);
  return 0;
}

void PrintStack(Stack *pStk)
{
  int i;
  for(i = 1; i <= pStk->top; i++)
    printf(" %d",pStk->array[i]);
  printf("\n");
}
void PrintAllBlocks(Stack **ppStk, int blockNum)
{
  int i;
  for(i = 0; i < blockNum; i++)
    {
      printf("%d:",i);
      PrintStack(ppStk[i]);
    }
}
int main(void)
{
  Stack **ppStkArray;
  int n;
  int i,j;
  char str1[10],str2[10];
  int srcData,dstData;
  int srcPos,dstPos;

  scanf("%d",&n);
  ppStkArray = malloc(n*sizeof(*ppStkArray));
  for(i = 0; i < n; i++)
    {  
      ppStkArray[i] = CreateStack();
      Push(ppStkArray[i],i);
    }
  /*  PrintAllBlocks(ppStkArray,n);

  printf("after popping %d\n",Pop(ppStkArray[2]));
  PrintAllBlocks(ppStkArray,n);*/
  while(1)
    {
      scanf("%s",str1);
      if(strcmp(str1,"quit")==0)
	break;
      scanf("%d %s %d",&srcData,str2,&dstData);
      if(srcData == dstData)
	continue;
      for(i = 0; i < n; i++)
	{
	  srcPos = Find(ppStkArray[i],srcData);
	  if(srcPos)
	  break;
	}
      for(j = 0; j < n; j++)
	{
	  dstPos = Find(ppStkArray[j],dstData);
	  if(dstPos)
	    break;
	}
      if(i == j)
	continue;
      else
	{
	  if(strcmp(str1,"move") == 0 && strcmp(str2, "onto") == 0)
	    MoveOnto(ppStkArray,i,srcPos,j,dstPos);
	  else  if(strcmp(str1,"move") == 0 && strcmp(str2, "over") == 0)
	    MoveOver(ppStkArray,i,srcPos,j,dstPos);
	  else  if(strcmp(str1,"pile") == 0 && strcmp(str2, "onto") == 0)
	    PileOnto(ppStkArray,i,srcPos,j,dstPos);
	  else  if(strcmp(str1,"pile") == 0 && strcmp(str2, "over") == 0)
	    PileOver(ppStkArray,i,srcPos,j,dstPos);
	  /*PrintAllBlocks(ppStkArray,n);*/
	}

    }
  PrintAllBlocks(ppStkArray,n);
  return 0;
}

分享到:
评论

相关推荐

    PKU POJ 1162 Building with Blocks解题报告

    ### PKU POJ 1162 Building with Blocks 解题报告 #### 题目概述 本题名为“Building with Blocks”,属于经典的积木搭建问题。题目要求利用一定数量的基本单位积木,搭建出特定的三维形状。积木的种类不超过12种,...

    The Blocks Problem

    题面

    POJ1390--blocks.rar

    标题“POJ1390--blocks.rar”指的是一个压缩包文件,用于提交给编程竞赛平台POJ(Programming Online Judge)的解决方案。POJ是一个在线的编程竞赛平台,程序员可以在这里提交自己的源代码来解决特定的算法问题。在...

    the_building_blocks

    the_building_blocks

    Code::Blocks

    Code::Blocks是一款强大的开源集成开发环境(IDE),它支持多种编程语言,包括Frotran、C++和Python等。在本文中,我们将深入探讨Code::Blocks的特性、用途以及如何利用它来编辑、修改和应用Frotran语言。 首先,让...

    POJ2286的代码

    The rotation game uses a # shaped board, which can hold 24 pieces of square blocks (see Fig.1). The blocks are marked with symbols 1, 2 and 3, with exactly 8 pieces of each kind.

    poj题目分类...

    POJ 题目分类详解 POJ(Purdue Online Judge)是一个知名的编程比赛平台,为编程爱好者和学生提供了大量的编程题目。然而,在做 POJ 题目的时候,如果没有分类的话,可能会感到很迷茫。因此,本文将对 POJ 题目进行...

    poj很多难题的源代码...

    【标题】"poj很多难题的源代码..." 涉及的知识点主要集中在算法和编程实践上,这里的“poj”通常是指北京大学的在线判题系统“Programming Online Judge”,它是国内较早的编程竞赛平台之一,吸引了众多程序员进行...

    new_blocks_for_the_kids

    new_blocks_for_the_kids

    A Fast Taboo Search Algorithm for the Job Shop Problem

    以上知识点提供了对标题《A Fast Taboo Search Algorithm for the Job Shop Problem》和描述中提到的各个方面深入的理解。涉及的标签“Taboo Search”和“Nowicki”指明了算法的关键技术和主要研究者。此外,从部分...

    Templates for the Solution of Linear Systems - Building Blocks for Iterative Methods.ps

    Templates for the Solution of Linear Systems - Building Blocks for Iterative Methods.ps

    scratch-blocks-develop.zip

    而`scratch-blocks`是Scratch项目的核心部分,它提供了用于构建代码块的可视化界面。这些代码块通过拖放方式组合,使得编程变得简单易懂,特别适合初学者。 `scratch-blocks-develop.zip`是一个压缩包,包含了已经...

    Building Blocks.dotx

    Building Blocks.dotx为word2007的页码模板,亲测有效,安装方法百度下即可

    code blocks for Novice

    ### Code::Blocks:初学者的理想选择 #### 一、概览与重要性 Code::Blocks是一款功能强大且用户友好的开源集成开发环境(IDE),专为C和C++程序员设计,尤其是初学者。其跨平台特性使其在Windows、Linux和macOS上...

    code blocks汉化包

    Code::Blocks是一款开源的、跨平台的C++集成开发环境(IDE),因其简洁、高效而深受程序员喜爱。这款IDE以其可扩展性和高度自定义性著称,允许用户根据自己的需求调整工作环境。汉化包是为非英语国家的用户提供方便...

    Microsoft.ApplicationBlocks.Data.dll

    Microsoft.ApplicationBlocks.Data.dll

    Built-In Building Blocks.dotx

    Built-In Building Blocks.dotx office2016 .

    code blocks

    code blocks

    Building Blocks.rar

    "Building Blocks.rar"这个压缩包提供了一个可能的解决方案,主要关注于使用"Building Blocks"功能来修复此类问题。Building Blocks是Word中一个强大的工具,它允许用户创建、存储和重复使用各种文档元素,如页眉、...

Global site tag (gtag.js) - Google Analytics