UVa-The Block Problem(101)

本文分享了一位程序员在使用C语言进行编程时遇到的问题,特别是涉及结构、链表和指针时的挑战。通过一系列代码实例,作者详细解释了如何避免常见的错误,如段溢出、无效指针分配等,并强调了C语言中指针使用的重要性。此外,还对比了两次尝试解决问题的不同方法,揭示了输入数据方式对程序正确性的影响。

当看完题目时感觉很简单,没想到折腾一天才搞好........让我泪奔........怎么老是WA,终于在第五次AC

总结原因就是C语言结构,链表,指针,当这些东西混合在一起很容易出错,往往一个段溢出错误要找半天,找到最后原来是自己的逻辑错误,分配了无效的指针,这就是折腾一天的教训,看来C语言指针真的很重要,功底不扎实就是容易出错!!!!

这是第一种情况的代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define COUNT 25
char s1[4]="move";
char s2[4]="pile";
char s3[4]="quit";
char s4[4]="onto";
char s5[4]="over";
char s6[20];
typedef struct Block_Problem
{
        char n;
        struct Block_Problem *next, *prev;
}BLOCK;

BLOCK *Point[COUNT], *p;

void BlockNum(BLOCK **a,BLOCK **b)
{
        int i=0;
        while(s6[i]!='\0')
        {
                if(s6[i]>='0' && s6[i]<='9')
                {
                        if(*a == NULL)
                                *a=p+(s6[i]-48);
                        else *b=p+(s6[i]-48);
                }
                i++;
        }
}
void moveTo()
{
        BLOCK *a=NULL, *b=NULL, *p1=NULL;
        BlockNum(&a,&b);
        p1=a;
        if(a->prev != NULL)
                (a->prev)->next=NULL;
        a->prev=NULL;
        while(p1->next !=NULL)
        {
                p1=p1->next;
                Point[p1->n]=p1;
                (p1->prev)->next=NULL;
                p1->prev=NULL;
        }
        p1=b;
        while(p1->next != NULL)
        {
                p1=p1->next;
                Point[p1->n]=p1;
                (p1->prev)->next=NULL;
                p1->prev=NULL;
        }
        b->next=a;
        Point[a->n]=NULL;
        a->prev=b;
}
void moveOver()
{
        BLOCK *a=NULL, *b=NULL, *p1=NULL;
        BlockNum(&a,&b);
        p1=a;
        if(a->prev != NULL)
                (a->prev)->next=NULL;
        a->prev=NULL;
        while(p1->next != NULL)
        {
                p1=p1->next;
                Point[p1->n]=p1;
                (p1->prev)->next=NULL;
                p1->prev=NULL;
        }
        while(b->next != NULL)
        {
                b=b->next;
        }
        b->next=a;
        Point[a->n]=NULL;
        a->prev=b;
}
void pileTo()
{
        BLOCK *a=NULL, *b=NULL, *p1=NULL;
        BlockNum(&a,&b);
        if(a->prev != NULL)
                (a->prev)->next=NULL;
        p1=b;
        while(p1->next != NULL)
        {
                p1=p1->next;
                Point[p1->n]=p1;
                (p1->prev)->next=NULL;
                p1->prev=NULL;
        }
        b->next=a;
        Point[a->n]=NULL;
        a->prev=b;
}
void pileOver()
{
        BLOCK *a=NULL, *b=NULL, *p1=NULL;
        BlockNum(&a,&b);
        if(a->prev != NULL)
                (a->prev)->next=NULL;
        while(b->next != NULL)
                b=b->next;
        b->next=a;
        Point[a->n]=NULL;
        a->prev=b;
}
void Print(int n)
{
        int i=0;
        BLOCK *p=NULL;
        for(i=0;i<n;i++)
        {
                printf("%d:",i);
                if(Point[i]!=NULL)
                {
                        printf(" %d",Point[i]->n);
                        p=Point[i]->next;
                        while(p!=NULL)
                        {
                                printf(" %d",p->n);
                                p=p->next;
                        }
                }
                printf("\n");
        }
}
int Legal()
{
        BLOCK *a=NULL, *b=NULL, *p1=NULL;
        BlockNum(&a,&b);
        if(a->n == b->n)
                return 0;
        else 
        {
                p1=a;
                while(p1->next != NULL)
                {
                        p1=p1->next;
                        if(p1->n == b->n)
                                return 0;
                }
                while(a->prev != NULL)
                {
                        a=a->prev;
                        if(a->n == b->n)
                                return 0;
                }
        }
        return 1;
}
int main()
{
        int n=0,i=0;
        while(scanf("%d",&n)!=EOF)
        {

                memset((void*)Point,0,sizeof(Point));
                p=(BLOCK*)malloc(n*sizeof(BLOCK));
                for(i=0; i<n; i++)
                {
                        Point[i]=p+i;
                        Point[i]->n=i;
                        Point[i]->next=NULL;
                        Point[i]->prev=NULL;
                }
                i=0;
                while(gets(s6))
                {
                        if(i ==0)
                        {
                                i++;
                                continue;
                        }
                        if(strncmp(s6,s3,4)==0)
                                break;
                        if(Legal()==0)
                                continue;
                        if(strncmp(s6,s1,4)==0)
                        {
                                if(strncmp(s6+7,s4,4)==0)
                                        moveTo();
                                else if(strncmp(s6+7,s5,4)==0)
                                        moveOver();
                        }
                        else if(strncmp(s6,s2,4)==0)
                        {
                                if(strncmp(s6+7,s4,4)==0)
                                        pileTo();
                                else if(strncmp(s6+7,s5,4)==0) 
                                        pileOver();
                        }

                }
        Print(n);
        free(p);
        }
        return 0;
}

第二种AC的代码(跟上一个代码比较,就是我在输入过程中只用了一种输入方式,两种不同的读入数据方式有可能导致的错误)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define COUNT 26
typedef struct Block_Problem
{
        char n;
        struct Block_Problem *next, *prev;
}BLOCK;
int n;
BLOCK *Point[COUNT], *p;
void moveTo(int a1, int b1)
{
        BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
        p1=a;
        if(a->prev != NULL)
                (a->prev)->next=NULL;
        a->prev=NULL;
        while(p1->next !=NULL)
        {
                p1=p1->next;
                Point[p1->n]=p1;
                (p1->prev)->next=NULL;
                p1->prev=NULL;
        }
        p1=b;
        while(p1->next != NULL)
        {
                p1=p1->next;
                Point[p1->n]=p1;
                (p1->prev)->next=NULL;
                p1->prev=NULL;
        }
        b->next=a;
        Point[a->n]=NULL;
        a->prev=b;
}
void moveOver(int a1, int b1)
{
        BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
        p1=a;
        if(a->prev != NULL)
                (a->prev)->next=NULL;
        a->prev=NULL;
        while(p1->next != NULL)
        {
                p1=p1->next;
                Point[p1->n]=p1;
                (p1->prev)->next=NULL;
                p1->prev=NULL;
        }
        while(b->next != NULL)
        {
                b=b->next;
        }
        b->next=a;
        Point[a->n]=NULL;
        a->prev=b;
}
void pileTo(int a1, int b1)
{
        BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
        if(a->prev != NULL)
                (a->prev)->next=NULL;
        p1=b;
        while(p1->next != NULL)
        {
                p1=p1->next;
                Point[p1->n]=p1;
                (p1->prev)->next=NULL;
                p1->prev=NULL;
        }
        b->next=a;
        Point[a->n]=NULL;
        a->prev=b;
}
void pileOver(int a1, int b1)
{
        BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
        if(a->prev != NULL)
                (a->prev)->next=NULL;
        while(b->next != NULL)
                b=b->next;
        b->next=a;
        Point[a->n]=NULL;
        a->prev=b;
}
void Print()
{
        int i=0;
        BLOCK *p=NULL;
        for(i=0;i<n;i++)
        {
                printf("%d:",i);
                while(Point[i]!=NULL)
                {
                        printf(" %d",Point[i]->n);
                        Point[i]=Point[i]->next;
                }
                printf("\n");
        }
}
int Legal(int a1, int b1)
{
        BLOCK *a=p+a1, *b=p+b1, *p1=NULL;
        if(a->n == b->n)
                return 0;
        else 
        {
                p1=a;
                while(p1->next != NULL)
                {
                        p1=p1->next;
                        if(p1->n == b->n)
                                return 0;
                }
                while(a->prev != NULL)
                {
                        a=a->prev;
                        if(a->n == b->n)
                                return 0;
                }
        }
        return 1;
}
void init()
{
        int i;
        memset((void*)Point,0,sizeof(Point));
        for(i=0; i<n; i++)
        {
                Point[i]=p+i;
                Point[i]->n=i;
                Point[i]->next=NULL;
                Point[i]->prev=NULL;
        }
}
int main()
{
        char s1[5], s2[5];
        int a,b;
        int i=0;
        scanf("%d",&n);
        p=(BLOCK*)malloc(n*sizeof(BLOCK));
        init();
        while(scanf("%s",s1) && s1[0] != 'q')
        {
                scanf("%d%s%d",&a,s2,&b);
                if(Legal(a,b)==0)
                        continue;
                if(s1[0]=='m' && s2[1]=='n')moveTo(a,b);
                if(s1[0]=='m' && s2[1]=='v')moveOver(a,b);
                if(s1[0]=='p' && s2[1]=='n')pileTo(a,b);
                if(s1[0]=='p' && s2[1]=='v')pileOver(a,b);

        }
        Print();
        free(p);
        return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值