Atcoder Beginner Contest 236 ABC 代码风格 格式#ifdef#else#endif ios::sync_with_stdio tie 异或 map容器 vector容器

在这里插入图片描述
8分钟a了前两个,然后第三个,头卡掉了。(记录一下悲惨的经历。
就继续磨题解吧。

琢磨题解的时候发现了这个:

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

学习一下,形式:

#ifdef 标识符
程序段1
#else
程序段2
#endif

意思是:当标识符已经被定义过(一般使用#define命令定义)则对程序段1进行编译,否则编译程序段2。

浅显理解一下

继续优化一下c++代码:

ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);

关于这个东西。
sync_with_stdio:是否兼容stdio的开关,c++中既可以使用printf也可以使用cout,也可以混用这两个输出方式。
关闭iostream的输入输出缓存,让cin和cout的效率与scanf和printf相差不大。

来看第一题:
输入一个字符串,交换第a和第b两个位置的字符,然后输出。
代码如下:

#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  string s;
  cin >> s;
  int a, b;
  cin >> a >> b;
  swap(s[a - 1], s[b - 1]);
  cout << s << '\n';
  return 0;
}

一点点代码风格,头文件,using namespace std;,和题解代码换行分开。
值得学习,使用纯c++,加上ios::sync_with_stdio(false);cin.tie(0);以提高输入输出效率。
交换字符,使用函数swap(a,b).

第二题,题意:输入n,从1到n都有四个数字,其中有一个数字有三个,输出这个数字。
我第一个思路是计数,cnt=3的那个数字输出,当然这样需要遍历两遍。

不妨考虑一下数学方法,一个数的偶数次异或结果是0,这不,最后不就只剩下那个3个的数了吗?既节省时间,又节省空间。太棒了!

代码:

#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  int x = 0;
  for (int i = 0; i < 4 * n - 1; i++) {
    int y;
    cin >> y;
    x ^= y;
  }
  cout << x << '\n';
  return 0;
}

值得学习的地方就是 x^=y 这个数学式子,巧妙的等效了一个开数组,一层遍历。

第三题就是卡掉脑袋的题。最高效的是用vector map做,还是使用的不熟练,继续巩固。

第三题是先输入n个字符串,再输入m个字符串,如果m中有n中的字符串,输出Yes,否则输出No。

代码:

#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<bool> res(n, false);
  map<string, int> mp;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    mp[s] = i;
  }
  for (int j = 0; j < m; j++) {
    string s;
    cin >> s;
    res[mp[s]] = true;
  }
  for (int i = 0; i < n; i++) {
    cout << (res[i] ? "Yes" : "No") << '\n';
  }
  return 0;
}

首先,忘了定义vector最常用的方法了???

//定义具有10个整型元素的向量,且给出的每个元素初值为1
vector<bool> res(n,0);
//意思是定义vector bool类型 res 大小为n 其中元素初始值为0

还不止这个,c++stl中很重要的map!

开始学习map容器(暴露自己又菜又懒了):
map是stl里的一个关联容器,,提供一对一的hash映射。(key与value)
map的底层结构是红黑树,红黑树对数据自动排序,故map中的元素自动有序。
map头文件#include< map> 当然万能头也行。
然后定义:std::map<string,int> personnel;
其中第一个类型是关键字的类型,第二个是存储对象的类型,本题就定义了string类型的关键字作为索引,并拥有相关联的指向int的指针。

这个代码还有一个很巧妙的地方,
string s;
cin >> s;
mp[s] = i;
使用string做索引,使用i做数据存储。想法很赞。
接下来的思路是,输入m的字符串,里面存在的使用res标记,最后输出。
其中还有值得学习的东西,最后的三目运算符
输出cout << (res[i] ? “Yes” : “No”);
要使用三目运算符把一个if-else的判断语句变成一句话,代码更简洁。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三元湖有大锦鲤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值