4. [2003年NOIP普及组] 乒乓球!!!!(疑惑已解决)

【问题描述】华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在11分制和21分制下,双方的比赛结果(截至记录末尾)。
比如现在有这么一份记录,(其中W表示华华获得一分,L表示华华对手获得一分):
WWWWWWWWWWWWWWWWWWWWWWLW
在11分制下,此时比赛的结果是华华第一局11比0获胜,第二局11比0获胜,正在进行第三局,当前比分1比1。而在21分制下,此时比赛结果是华华第一局21比0获胜,正在进行第二局,比分2比1。如果一局比赛刚开始,则此时比分为0比0。
你的程序就是要对于一系列比赛信息的输入(WL形式),输出正确的结果。
输入
输入包含若干行字符串(每行至多20个字母),字符串有大写的W、L和E组成。其中E表示比赛信息结束,程序应该忽略E之后的所有内容。
输出
输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。其中第一部分是11分制下的结果,第二部分是21分制下的结果,两部分之间由一个空行分隔。
样例输入
WWWWWWWWWWWWWWWWWWWW
WWLWE
样例输出
11:0
11:0
1:1

21:0
2:1
提示
如果一名选手为11(21)分,而另一名选手与其分的差距小于2,则比赛继续进行,直到差距等于2为止。
 
AC代码如下:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<string>
 6 #include<cmath>
 7 using namespace std;
 8 string  a,b;//b为总的字符串 
 9 int win,lose,ah,bh;
10 string scan()
11 {
12     string all,temp;
13     while(getline(cin,temp))
14     {
15         all+=temp;
16         if(all.find('E')!=std::string::npos)
17             break;
18     }
19     return all.substr(0,all.find('E'))+"E";
20 }
21 bool t=0;
22 void match(string s,int h,int size)
23 {
24     int i=0;
25     while(1)
26     {
27         if((win>=h||lose>=h)&&abs(win-lose)>=2)
28         {
29             printf("%d:%d\n",win,lose);    
30 //            s.erase(0,win+lose);//左闭右开 
31             win=0,lose=0;            
32         }
33         if(s[i]=='W')win++;
34         if(s[i]=='L')lose++;
35         if(s[i]=='E')
36         {
37             printf("%d:%d\n",win,lose);
38             win=0,lose=0;
39             return;
40         }
41 
42     i++;
43     }
44 }
45 int main()
46 {
47     b=scan();
48     bh=b.length();
49     match(b,11,bh);
50     cout<<endl;
51     match(b,21,bh);
52     return 0;
53  } 
54  

我们一部分一部分来进行拆解

第一部分:输入

1     while(1)
2     {
3         ah=0;
4         cin>>a;
5         ah=a.size();
6         b+=a;
7         bh+=ah;
8         if(a[ah-1]=='E') break;
9     }

此代码会导致内存超限:

我的疑惑:a每次只占用了属于a的地址,为什么会内存超限?

已解决:

string类型的定义与int型并不一样

对于全局变量,int赋初值为零但是string并没有为他开辟空间

因此我们要这么写 string a="",b=""; 来为这个变量开辟空间

或者我们可以这么写

1 string s="",s1="";
2 while(s.find('E')==-1)
3 {
4     cin>>s1;
5     s+=s1;
6 }

 

学习fys写法:

 1 string scan()
 2 {
 3     string all,temp;
 4     while(getline(cin,temp))
 5     {
 6         all+=temp;
 7         if(all.find('E')!=std::string::npos)
 8             break;
 9     }
10     return all.substr(0,all.find('E'))+"E";
11 }

因此我们需要补充string的一些常用函数

 

 

第二次做:

 1 #include<bits/stdc++.h>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<string>
 7 #include<cmath>
 8 using namespace std;
 9 
10 int len;
11 
12 string scan();
13 void match(int rule,string s);
14 void print(int a,int b);
15 
16 int main()
17 {
18     string a=scan();
19     len=a.length();//误点2:忘记删调试 
20     match(11,a);
21     cout<<endl;
22     match(21,a);
23     return 0;
24 }
25 
26 string scan()
27 {
28     string all,temp;
29     while(getline(cin,temp))
30     {
31         all+=temp;
32         if(all.find('E')!=std::string::npos)
33         break;        
34     }
35     return all.substr(0,all.find('E'))+'E';
36 }//一定要背过 
37 
38 
39 void print(int a,int b)
40 {
41     printf("%d:%d\n",a,b);
42 }
43 void match(int rule,string s)
44 {
45     int k=0,sc1=0,sc2=0,i=0;
46     while(1)
47     {
48         if((sc1>=rule||sc2>=rule)&&abs(sc1-sc2)>=2)//结束本局,进行下一局 
49         {
50             print(sc1,sc2);
51             sc1=sc2=0;
52         } 
53         if(s[i]=='W')sc1++;
54         if(s[i]=='L')sc2++;
55         if(s[i]=='E')//结束 
56         {
57             print(sc1,sc2);
58             sc1=sc2=0;//误点1 
59             break;
60         }
61         i++;
62     }
63     
64 }

补充:

1.输入相关

2.substr截取函数

substr(a)截取从下标0 到a的部分;

substr(a,b)截取从下标a开始的b个数据;

(这b个数据包括a)

posted @ 2022-08-21 19:55  要不要吃哈密瓜  阅读(52)  评论(0编辑  收藏  举报