感觉上自己逻辑清楚,但是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的访问:
- 通过下标访问:
map<char,int> mp;
mp['c'] = 20;
mp['c'] = 30;
printf("%d\n",mp['c']); // 结果为30
- 通过迭代器访问
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常用函数:
- find()
find(key)返回键为key 的映射的迭代器,时间复杂度为O(log~N),N为map中映射的个数。 - erase()
删除单个元素:mp.erase(it) // it为迭代器;mp.erase(‘b’)
删除一个区间内的所有元素:mp.erase(first,last) // - size() 获得map映射的对数
- 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();
}
常见用途:
- 需要建立字符(或字符串)与整数之间映射的题目,使用map可以减少代码量。
- 判断大整数或者其他类型数据是否存在的题目,可以把map当bool数组用
- 字符串和字符串的映射也可能会遇到。
勉励
打卡第六天,加油ヾ(◍°∇°◍)ノ゙
感悟:如果你嫌弃学习麻烦,那你就永远学不会。