题目描述:猜数字游戏大家玩过没?经典的规则是给出一个四位数,然后你去猜。如那个数是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; }

评论