正文

习题 43:猜数字★2008-02-20 15:21:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/yaotou/32793.html

分享到:

题目描述:猜数字游戏大家玩过没?经典的规则是给出一个四位数,然后你去猜。如那个数是1357,你猜1234的话,就给出1A1B,这是什么意思呢?nA表示有n个数的位置猜对了,nB表示有n个数猜对了,但位置不对,如果你再猜2351当然给出2A1B了,如果你猜2468,那就是0A0B了。现在,把四位数扩展到n位,由数字扩展到字符,输入两个字符串,你判断出猜对位置的和猜对了但位置不对的。如abcdefg和aceg123,结果就是1A3B 输入:多组测试数据,每组占一行,每行有两个字符串,串长小于10000,用空格分隔开 输出:输出这两个字符串比较的结果 样例输入:1357 1234abcdefg aceg123AaAa AAaa121212 2121212211Qq qqGame 样例输出:1A1B1A3B2A2B0A6B1A0B 我的代码: [code] #include<iostream>#include<cstring>using namespace std; const int Max=10000; int main(){ char A[Max],B[Max],F[Max]; int i=0,j=0,Alen=0,Blen=0,len=0; int Ncount=0,Pcount=0; cin>>A>>B; Alen=strlen(A); Blen=strlen(B); len=Alen>Blen?Alen:Blen; for(i=0;i<len;i++)  //找出相同的 {  if(A[i]==B[i]) Ncount++; } for(i=0;i<Alen;i++)  //flag  F[i]=0; for(j=0;j<Blen;j++)  //找出B中与A相同字符的个数,   for(i=0;i<Alen;i++)    {   if( (B[j]==A[i]) && F[i]!=1 )   {    Pcount++;    F[i]=1;    break;   }     }     //Pcount-Ncount则为猜对了,但位置不对的  cout<<Ncount<<"A"<<Pcount-Ncount<<"B"<<endl; return 0;} [/code] G++: Compile OKTest  1:    Wrong Answer--------------------------------Problem ID     43Test Result    Wrong AnswerTotal Time     NULLTotal Memory   168 Kb / 65536 KbCode Length    566 Bytes 不知道什么地方错了。。。 哪位帮忙看看?~~~谢谢..   别人的代码 一、 /*习题 43:猜数字★编译环境:Visual C++ 6.0*/ #include <stdio.h>#include <string.h> #define N 10000 struct NUM_STRUCT{        char p[N];        int flag[N];}; static struct NUM_STRUCT p1, p2; void Calculate(){        int A = 0, B = 0;        // 先找出相同的        int lenA = strlen(p1.p);        int lenB = strlen(p2.p);         memset(p1.flag, 1, N);        memset(p2.flag, 1, N);         struct NUM_STRUCT *pMain = &p1;        struct NUM_STRUCT *pSub = &p2;        if(lenB > lenA)        {                pMain = &p2;                pSub = &p1;                 int temp = lenA;                lenA = lenB;                lenB = temp;        }         int i;        for(i = 0; i < lenB; i ++)        {                if(pMain->p[i] == pSub->p[i])                {                        A ++;                        pMain->flag[i] = pSub->flag[i] = 0;                }        }         // 再找出位置不同的        for(i = 0; i < lenA; i ++)        {                for(int j = 0; j < lenB; j ++)                {                        if(i != j && pMain->flag[i] && pSub->flag[j])                        {                                if(pMain->p[i] == pSub->p[j])                                {                                        B ++;                                        pSub->flag[j] = 0;                break;                                }                        }                                        }        }        printf("%dA%dB\n", A, B);} int main(){        while(scanf("%s", p1.p) != EOF)        {                scanf("%s", p2.p);                 Calculate();        }         return 0;}   二、 #include<stdio.h>int main(){    int A,B,m;    unsigned char a[10001],b[10001];    int ca[255],cb[255];    int length1,length2,minlength;    while(scanf("%s%s",a,b)!=EOF)    {           for(m=0;m<255;m++)        {cb[m]=0;ca[m]=0;}        A=0;B=0;        for(m=0,length1=0;a[m]!='\0';m++)        length1++;        for(m=0,length2=0;b[m]!='\0';m++)        length2++;         minlength=length1<length2?length1:length2;        for(m=0;m<minlength;m++)        if(b[m]==a[m]) {a[m]='\0';b[m]='\0';}                for(m=0;m<length2;m++)        cb[b[m]]++;        for(m=0;m<length1;m++)        ca[a[m]]++;        A=ca[0];        for(m=1;m<255;m++)        B+=ca[m]<cb[m]?ca[m]:cb[m];            printf("%dA%dB\n",A,B);        for(m=0;m<10001;m++)        a[m]=b[m]='\0';    }    return 0;}   猜数字问题的解题回想(习题43)转自http://yzfy.org/bbs/viewthread.php?tid=309&extra=page%3D1 易错点:1.貌似test3的测试数据有10000个...所以数组至少得10001个元素,最后一  个元素存储结束符'\0',如果元素少了就会有越界的危险...但是编译器是不  会提示越界的(这点比较重要).2.我们自己测试的时候只能输入数字,字母,一些常见的符号,一般ASCII码都小  于126,但是在test5中的一些字符是超出了126的,是一些我们自己不能测试  的字符,要是没考虑到这点某些算法就会出错,但自己还察觉不了.(BS一下燕  子的数据!)难点:1.对于B数目的计算容易出错.不能正确的与A的计算分开进行互不干扰.2.TLE......万恶的TLE.....算法不好就TLE了....(这里再BS一下燕子严格的  时间限制)解决问题:易错点1.数组设10001个元素2.考虑用unsigned char来定义储存字符串的数组.(特别说明,某些算法不需要  考虑字符的ASCII代码是多少,那我觉得可以用char来定义,但是貌似这类算  法是普遍要超时的...但不排除有人成功例子出现)难点1.先算完A,再算B(我是边算A边把满足A增加1条件的元素赋值为'\0',这样对算  B时,'\0'就不会干扰其计算了)2.只能通过算法来改进.(我考虑过两种,一种TLE一种通过,下文会附上)我对这道题的解答从猜数字这个帖的10页,140#开始...大家如果去看看就能清楚地见证这几个难点易错点的克服过程.我把各次解答的错误原因附在这里,方便比对.140#   ==>  数组越界,算法耗时(易错1难点2)142#   ==>  算法耗时(难点2)144#   ==>  B计算时与A牵扯,算法耗时(难点1难点2)146#   ==>  算法耗时(难点2)148#   ==>  算法耗时(难点2)总结下这种算法:用a,b两个数组存字符串,用循环一一测试a,b数组中相同位置              的字符是否相同,相同就都赋'\0'并A++,循环结束后得出A值.              再套用两个循环,依次对a中每一个字符,在b中依次寻找相同的              字符,找到后B++,对b中此元素赋'\0'防止2次使用,直到a中元              素全部搜索完,那B也出来了.148#改进了下,当搜索a数组中靠              前元素时,从b前往后搜索相同元素,当搜索到a数组中靠后元素时,              从b后往前搜索相同元素...这样勉强快了点,过了text3..没              过text4...150#   ==> 没用unsigned char(易错2)152#   ==> 同上154#   ==> 同上156#   ==> 用unsigned char来定义的字符数组不能用strlen()函数测长度158#   ==> 通过!说明下这种算法:用unsigned char定义a,b.依旧先依次对照a,b中相同位置的              字符,相同就赋'\0'.定义两个255个元素的数组,ca,cb.              以a元素中各个元素的ASCII代码做为下标(这个词用在这里不              晓得准确不?)找到ca数组中相应元素并自加一,代表这个字符出              现了一次,比如a中有字符A,其ASCII代码为65,则将ca[65]++              ;之所以要用unsigned char的原因也在这里,比如ā字符,其              ASCII码为161,如果定义为char,char的范围而是-128到127,              最高位为符号位,所以ā字符转换为整型是一负值,这样在ac数              组里根本找不到下标是负号的元素...所以是不对的,而unsin              gned char范围是0到255,包含所有的字符,就能解决这个问              题.同理把b中元素出现情况在cb中统计出来,这样A的大小就              是ca或cb第一个元素的大小(2者是相同的),再用一个循环,依              次比较ca和cb相同位置的元素大小,B加上2者间小的那个再赋跟              B,直到循环结束,这样B值也求出了,这种算法不TLE...3:40了,有点困了,最后附上通过的代码:#include<stdio.h> int main() {         int A,B,m;         unsigned char a[10001],b[10001];         int ca[255],cb[255];         int length1,length2,minlength;         while(scanf("%s%s",a,b)!=EOF)         {                    for(m=0;m<255;m++)       /*清零很重要哈*/                 {cb[m]=0;ca[m]=0;}                 A=0;B=0;                 for(m=0,length1=0;a[m]!='\0';m++)   /*测出a,b字符                 length1++;                            串长度*/                 for(m=0,length2=0;b[m]!='\0';m++)                 length2++;                 minlength=length1<length2?length1:length2;  /*将短的长度赋跟minlength方便循环                 for(m=0;m<minlength;m++)                                      的使用*/                 if(b[m]==a[m]) {a[m]='\0';b[m]='\0';}   /*统计满足A的字符*/                 for(m=0;m<length2;m++)/*在cb,ca中分别统计b,a中字符出现情                 cb[b[m]]++;            况*/                 for(m=0;m<length1;m++)                 ca[a[m]]++;                 A=ca[0];          /*数组第一个元素大小即是A*/                 for(m=1;m<255;m++)                 B+=ca[m]<cb[m]?ca[m]:cb[m];/*叠加算出B*/                       printf("%dA%dB\n",A,B);                 for(m=0;m<10001;m++)   /*最后清零不要忘记*/                 a[m]=b[m]='\0';         }         return 0; }               

阅读(2188) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册