- 浏览: 73404 次
- 性别:
- 来自: 杭州
最新评论
关键在于彻底理解题目中搬积木的几个命令的含义,见具体分析
如果还不能理解题意,那么找一个正确通过的代码,编译并输入测试数据,查看其每一个命令的执行情况。如我的代码中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; }
发表评论
-
最小c编译器
2011-11-08 14:09 1508最小c编译器(来源 (最好在linux下操作))代码有好几个 ... -
the development of c language(转)
2011-11-08 09:25 1357c语言之父Dennis Ritchie 写的关于c语言开发历 ... -
C语言,你真的弄懂了么?
2011-11-07 12:42 1780程序(来源 ): #include <stdi ... -
pe文件格式实例解析
2011-11-07 10:05 0环境:windows xp 速龙3000+(即x86兼容32位 ... -
小型elf "Hello,World"程序
2011-11-06 23:59 1384参考链接:http://timelessname.com/el ... -
elf文件格式实例解析
2011-11-05 23:00 6381试验环境:archlinux 速龙3000+(即x86兼 ... -
高质量的c源代码
2011-11-03 10:18 1189现在自由软件及开源软件越来越流行,有大量的附带源程序 ... -
fltk 库
2011-09-26 19:47 1865fltk是一个小型、开源、支持OpenGL 、跨平台(win ... -
《Introduction to Computing Systems: From bits and gates to C and beyond》
2011-09-25 23:33 2195很好的一本计算机的入门书,被很多学校采纳作为教材,作者Yale ... -
csapp bufbomb实验
2011-09-16 14:21 4646csapp (《深入理解计算机系统》)一书中有一个关于缓冲区 ... -
the blocks problem(uva 101 or poj 1208)
2011-09-11 20:56 0题目描述见:uva 101 or poj 1208 ... -
部分排序算法c语言实现
2011-09-02 14:51 1027代码比较粗糙,主要是用于对排序算法的理解,因而忽略了边界和容错 ... -
编译器开发相关资源
2011-08-31 08:40 1226开发编译器相关的一些网络资源: how difficu ... -
zoj 1025 Wooden Sticks
2011-07-23 20:25 974题目见:zoj 1025 先对木棒按照长度进行排序,然后再计 ... -
zoj 1088 System Overload
2011-07-23 17:30 1179约瑟夫环 (josephus problem )问题, ... -
zoj 1091 Knight Moves
2011-07-23 09:05 858题目见zoj 1091 使用宽度搜索优先来求解, ... -
zoj 1078 palindrom numbers
2011-07-22 19:31 1154题目见zoj 1078 主要是判断一个整数在基数为2 ... -
zoj 1006 do the untwist
2011-07-22 13:24 946题目见zoj 1006 或poj 1317 简单 ... -
zoj 3488 conic section
2011-07-22 12:23 1019题目见zoj 3488 很简单的题目,却没能一次搞定,因 ... -
zoj 1005 jugs
2011-07-22 11:43 855题目内容见zoj1005 由于A,B互素且A的容 ...
相关推荐
### PKU POJ 1162 Building with Blocks 解题报告 #### 题目概述 本题名为“Building with Blocks”,属于经典的积木搭建问题。题目要求利用一定数量的基本单位积木,搭建出特定的三维形状。积木的种类不超过12种,...
题面
标题“POJ1390--blocks.rar”指的是一个压缩包文件,用于提交给编程竞赛平台POJ(Programming Online Judge)的解决方案。POJ是一个在线的编程竞赛平台,程序员可以在这里提交自己的源代码来解决特定的算法问题。在...
the_building_blocks
Code::Blocks是一款强大的开源集成开发环境(IDE),它支持多种编程语言,包括Frotran、C++和Python等。在本文中,我们将深入探讨Code::Blocks的特性、用途以及如何利用它来编辑、修改和应用Frotran语言。 首先,让...
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(Purdue Online Judge)是一个知名的编程比赛平台,为编程爱好者和学生提供了大量的编程题目。然而,在做 POJ 题目的时候,如果没有分类的话,可能会感到很迷茫。因此,本文将对 POJ 题目进行...
【标题】"poj很多难题的源代码..." 涉及的知识点主要集中在算法和编程实践上,这里的“poj”通常是指北京大学的在线判题系统“Programming Online Judge”,它是国内较早的编程竞赛平台之一,吸引了众多程序员进行...
new_blocks_for_the_kids
以上知识点提供了对标题《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
而`scratch-blocks`是Scratch项目的核心部分,它提供了用于构建代码块的可视化界面。这些代码块通过拖放方式组合,使得编程变得简单易懂,特别适合初学者。 `scratch-blocks-develop.zip`是一个压缩包,包含了已经...
Building Blocks.dotx为word2007的页码模板,亲测有效,安装方法百度下即可
### Code::Blocks:初学者的理想选择 #### 一、概览与重要性 Code::Blocks是一款功能强大且用户友好的开源集成开发环境(IDE),专为C和C++程序员设计,尤其是初学者。其跨平台特性使其在Windows、Linux和macOS上...
Code::Blocks是一款开源的、跨平台的C++集成开发环境(IDE),因其简洁、高效而深受程序员喜爱。这款IDE以其可扩展性和高度自定义性著称,允许用户根据自己的需求调整工作环境。汉化包是为非英语国家的用户提供方便...
Microsoft.ApplicationBlocks.Data.dll
Built-In Building Blocks.dotx office2016 .
code blocks
"Building Blocks.rar"这个压缩包提供了一个可能的解决方案,主要关注于使用"Building Blocks"功能来修复此类问题。Building Blocks是Word中一个强大的工具,它允许用户创建、存储和重复使用各种文档元素,如页眉、...