USACO1.1.2 Greedy Gift Givers

来源:互联网 发布:vmware怎么安装mac os 编辑:程序博客网 时间:2024/04/28 01:23

这道题是USACO的第二题,我感觉这道题也没什么难的,关键就在于如何将gift1.in中的数据正确读到程序中。先上参考答案的代码,然后是我看完代码后的心得体会。再过几道题,我就开始自己做,就把前几道题当做例题来熟悉。

/*ID: zhenliu2PROG: gift1LANG: C*/#include <stdio.h>#include <string.h>#include <assert.h>#define MAXPEOPLE 10#define NAMELEN 32typedef struct Person Person;struct Person{    char name[NAMELEN];    int total;};Person people[MAXPEOPLE];int npeople;void addPerson(char * name);Person * lookup(char * name);int main(void){    char name[NAMELEN];//临时存名字。    FILE * fin,* fout;    Person * giver , * receiver;    int i,np,amt,ng;    fin=fopen("gift1.in","r");    fout=fopen("gift1.out","w");    if(fin==NULL||fout==NULL)        assert(0);    fscanf(fin,"%d",&np);    assert(np<=MAXPEOPLE);    for(i=0;i<np;i++)    {        fscanf(fin,"%s",name);        addPerson(name);    }    for(i=0;i<np;i++)    {        fscanf(fin,"%s %d %d",name,&amt,&ng);        giver=lookup(name);        for(i=0;i<ng;i++)        {            fscanf(fin,"%s",name);            receiver=lookup(name);            giver->total-=amt/ng;            receiver->total+=amt/ng;        }    }    for(i=0;i<np;i++)    {        fprintf(fout,"%s %d\n",people[i].name,people[i].total);    }    fclose(fin);    fclose(out);    return 0;}void addPerson(char * name){    assert(npeople<=MAXPEOPLE);    strcpy(people[npeople].name,name);    npeople++;}Person * lookup(char * name){    int i;    for(i=0;i<npeople;i++)        if(strcmp(people[i].name,name)==0)            return &people[i];    assert(0);}

关于这份代码,我有如下心得:
首先这份代码让我学会了如何使用assert()函数。这个函数我刚开始用着很不习惯,但直到这份代码我在自己默写的时候调试出了bug之后才发现它真的挺好用的。assert()函数在头文件assert.h中,他有一个参数,只要这个参数不是0,那么他就像不存在一样。但只要该参数的值是0,那么他会立刻终止整个程序的执行,然后报错。之所以我变得这么喜欢这个函数是因为它在这道题的调试过程中帮我发现了一个错误,这才让我对它刮目相看,这个错误稍后我会在下面的心得中说到。
其次,这道题巩固了我对strcmp()和strcpy()函数的使用。这两个函数都是在string.h这个头文件中的,strcmp的作用是比较两个字符串,这两个字符串就是这个函数的两个参数,这个函数一般用来判断两个字符串是否相等,相等返回0,否则根据每个字母的ASCII码来计算返回值的正负。但在这里我们只是判断是否相等。strcpy()这个函数是复制字符串,他也有两个参数,作用是把后面参数的字符串复制到前面的参数中,这里的复制,是完全替换参数一所指向的地址空间的内容,因为这个函数把参数二的‘\0’也复制过去了。
然后就是我的刚才提到的错误了,我的错误在addPerson()这个函数中,我忘记了npeople++这一步,导致在调用了lookup()函数时运行到了assert(0);那一步。导致程序退出。而通过assert()这个函数也很快让我发现了这个错误。
最后,是我觉得最大的收获:这道题巩固了我结构体的知识,让我对结构体有了更深的理解,也教会了我如何使用结构体的思路来处理问题。我承认现在我的编程水平很一般,但我会多多积累经验,然后学以致用来提高自己的。