代码也需要减肥,如何让代码变得精致一些?map的使用,例题解析PAT1018 锤子剪刀布 (20分)

   日期:2020-05-10     浏览:92    评论:0    
核心提示:感觉上自己逻辑清楚,但是OJ上就是不AC,当自己代码冗余,繁琐时就会 容易出现问题,因此要学会精简代码,这样找bug也容易找。map例题解析:map如何理解map中的映射:如何定义map:map的访问:map常用函数:常见用途:例题解析:PAT 1018 锤子剪刀布 (20分)试题内容:大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。input输入第 1 行给出正整数

感觉上自己逻辑清楚,但是OJ上就是不AC,当自己代码冗余,繁琐时就会 容易出现问题,因此要学会精简代码,这样找bug也容易找。

map

    • 例题解析:
    • map
      • 如何理解map中的映射:
      • 如何定义map:
      • map的访问:
      • map常用函数:
      • 常见用途:

例题解析:

PAT 1018 锤子剪刀布 (20分)

试题内容:

大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:

现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。

input

输入第 1 行给出正整数 N(≤10
​5​ ),即双方交锋的次数。随后 N 行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C 代表“锤子”、J 代表“剪刀”、B 代表“布”,第 1 个字母代表甲方,第 2 个代表乙方,中间有 1 个空格。

output

输出第 1、2 行分别给出甲、乙的胜、平、负次数,数字间以 1 个空格分隔。第 3 行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有 1 个空格。如果解不唯一,则输出按字母序最小的解。

Sample Input

10
C J
J B
C B
B B
B C
C C
C B
J B
B C
J J

Sample Output

5 3 2
2 3 5
B B

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int mMax = 100010;
typedef struct cjb{
	int num;
	char alp;
}CJB;
int couter_a=0,couter_b=0,couter=0,n;
char cjb_a[mMax],cjb_b[mMax];
CJB x[3], y[3];
void win(char a,char b){
	if(a=='B'&&b=='C'){
		couter_a++;
		x[0].num++; 
		x[0].alp = 'B';
	}
	else if(a=='C'&&b=='J'){
		couter_a++;
		x[1].num++; //c
		x[1].alp = 'C'; 
	}
	else if(a=='J'&&b=='B'){
		couter_a++;
		x[2].num++; //J
		x[2].alp = 'J';
	}
	else if(a=='C'&&b=='B'){
		couter_b++;
		y[0].num++; //B
		y[0].alp = 'B'; 
	}
	else if(a=='J'&&b=='C'){
		couter_b++;
		y[1].num++; //C
		y[1].alp = 'C';
	}
	
	else if(a=='B'&&b=='J'){
		couter_b++;
		y[2].num++; //J
		y[2].alp = 'J';
	}
	else{
		couter++;
	}	
}
int main(){
	scanf("%d",&n); 
	for(int i=0;i<n;i++){
		getchar(); 
		scanf("%c %c",&cjb_a[i],&cjb_b[i]);
		win(cjb_a[i],cjb_b[i]);	
	}
	printf("%d %d %d\n",couter_a,couter,couter_b);
	printf("%d %d %d\n",couter_b,couter,couter_a);
	char a_alp = 'B',b_alp = 'B';
	int a_num = x[0].num,b_num = y[0].num;
	for(int i=1;i<3;i++){
		if(x[i].num > a_num){
			a_alp = x[i].alp;
			a_num = x[i].num; 
		}
		if(y[i].num > b_num){
			b_num = y[i].num;
			b_alp = y[i].alp;
		}  
	}
	printf("%c %c\n",a_alp,b_alp);
	return 0;
}

刚开始写的代码,emmm,冗余繁杂,主要找BUG找了半天呜呜。

#include <cstdio>
#include <map>
using namespace std;
const int mMax = 100010;
int j_input[mMax],y_input[mMax],n;
int j_couter=0,y_couter=0,couter=0;
map <char,int> j,y;
void win(char a, char b)
{
	if((a=='B'&&b=='C')||(a=='C'&&b=='J')||(a=='J'&&b=='B')){
		j[a]++;
		j_couter ++;
	}
	else if((a=='C'&&b=='B')||(a=='J'&&b=='C')||(a=='B'&&b=='J')){
		y[b]++;
		y_couter ++;
	}
	else couter++;
}
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		getchar();
		scanf("%c %c",&j_input[i],&y_input[i]);
		win(j_input[i],y_input[i]);
	}
	printf("%d %d %d\n",j_couter,couter,y_couter);
	printf("%d %d %d\n",y_couter,couter,j_couter);
	printf("%c",(j['B']<j['C'])?((j['C']<j['J'])?'J':'C'):((j['B']<j['J'])?'J':'B'));
	printf(" %c\n",(y['B']<y['C'])?((y['C']<y['J'])?'J':'C'):((y['B']<y['J'])?'J':'B')); 
	return 0;
}

map

知识点补充:

map(映射)
在头文件==<map>==中:

如何理解map中的映射:

  • 相当于array[0] = 5.20,是将int 型映射到double型。
  • map 可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器)。

如何定义map:

  • 字符串到整型的映射:map<string,int> mp; 字符串必须只能用string表示。
  • 字符型到整型的映射:map<char,int> mp;
  • set容器到字符串类型的映射:map<set<int>, string> mp;

map的访问:

  1. 通过下标访问:
map<char,int> mp;
mp['c'] = 20;
mp['c'] = 30printf("%d\n",mp['c']); // 结果为30
  1. 通过迭代器访问
for(auto it = j.begin(); it!= m.end()lit++){
	cout<< it->fist<<" "<< it->second << endl;
}
// 访问map的第⼀个元素,输出它的键和值
cout << m.begin()->first << " " << m.begin()->second << endl;
// 访问map的最后⼀个元素,输出它的键和值
cout << m.rbegin()->first << " " << m.rbegin()->second << endl;
// 输出map的元素个数
cout << m.size() << endl;

map常用函数:

  1. find()
    find(key)返回键为key 的映射的迭代器,时间复杂度为O(log~N),N为map中映射的个数。
  2. erase()
    删除单个元素:mp.erase(it) // it为迭代器;mp.erase(‘b’)
    删除一个区间内的所有元素:mp.erase(first,last) //
  3. size() 获得map映射的对数
  4. clear() 清空map
map<char,int> mp;
mp['a'] = 1;
map <char,int> mp;
int main(){
	mp['a'] = 1;
	mp['b'] = 2;
	auto it = mp.find('a'); //auto 可以让编译器根据初始值类型直接推断变量的类型
	printf("%c %d\n",it->first,it->second);
	mp.erase(it,mp.end());//删除it之后的所有映射。
	mp.erase(it) //就把mp['a']删除了
	mp.clear();
}

常见用途:

  1. 需要建立字符(或字符串)与整数之间映射的题目,使用map可以减少代码量。
  2. 判断大整数或者其他类型数据是否存在的题目,可以把map当bool数组用
  3. 字符串和字符串的映射也可能会遇到。

勉励
打卡第六天,加油ヾ(◍°∇°◍)ノ゙ 感悟:如果你嫌弃学习麻烦,那你就永远学不会。

 
标签: 文章标签: c++
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服