1497 字
7 分钟
L1-016~L1-020的笔记
Waiting for api.github.com...
P.S. 这份笔记同步发布在我的博客上,建议在博客中查看以享受完整的MD Extended Features. 你可以点此快速跳转到相应页面,我的博客地址为https://samera2022.github.io
L1-016
代码部分
#include <bits/stdc++.h>using namespace std;typedef long long ll;//spec A
void solve(const string s[], int size);
int weight[] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};char validate[] = "10X98765432";
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int N; cin>>N; string s[N]; for (int i = 1; i <= N; i++) { string content; cin>>content; s[i-1] = content; } solve(s, N); return 0;}
void solve(const string s[], const int size) { int errors = 0; vector<string_view> vsv; for (int i = 1; i <= size; i++) { const string &content = s[i-1]; int temp = 0; bool isDigit = true; for (int j = 1; j <= 17; j++) { if (isdigit(content[j-1])) temp += (content[j-1]-'0') * weight[j-1]; else { isDigit = false; break; } } if (validate[temp%11]!=content[17] || !isDigit) { errors++; vsv.push_back(content); } } if (vsv.empty()) cout<<"All passed"; else for (const string_view sv : vsv) cout<<sv<<"\n";}笔记部分
string s[]仅在其定义域中能够获取其大小。获取大小的方式有如下两种:①sizeof(s)/sizeof(s[0])通过整个数组占用的字节数除以单个元素占用的字节数; ②begin(s)-end(s)通过指针相减来计算元素个数。说实在话,这两种不如直接使用定义string s[]长度的变量了。- 需要注意的是: ①
s->length();和s->size();获取的不是s[]的大小,而是s[0]的长度; ②将数组s[]作为参数传入函数后,其会发生指针退化,即数组丢失了其长度信息和数组类型属性,隐式地转换成指向其第一个元素的指针。这导致无法在传入的函数中正确获取其长度。 - 向
vector中压入数据使用的是vector.push_back(),这会将新的元素放在队尾。 string_view是保存string的引用的一个容器,cout方法有对其的兼容。
for (int i = 1; i <= N; i++) { string content; cin>>content; s[i-1] = content; }- 针对这一段循环输入,有以下几种简洁的替代方案:
- ①(定长数组或vector)
for (string& content : s) cin >> content; - ②(定长数组或vector)
copy_n(istream_iterator<string>(cin), N, (定长数组) s | (vector) s.begin());需要补充的是:(定长数组) s这里的s是以指向首元素的指针(迭代器)传入的。 - ③(vector)
vector<string> s{istream_iterator<string>(cin), istream_iterator<string>()}; - ④(vector)重载位右移运算符
istream& operator>>(istream& is, vector<T>& v) { for (auto& x : v) is >> x; return is;}而后vector<string> s(N); cin >> s;
L1-017
代码部分
#include <bits/stdc++.h>using namespace std;typedef long long ll;
void solve(string& content);
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); string content; cin>>content; solve(content); return 0;}
void solve(string& content) { bool isNegative = false; if (!isdigit(content[0])) { content.erase(remove(content.begin(),content.end(),'-'),content.end()); isNegative = true; } int cnt = 0; const int len = static_cast<int>(content.length()); const bool isEven = (content[len-1]-'0')%2==0; for (int i = 1; i <= len; i++) if (content[i-1]=='2') cnt++; double res = static_cast<double>(cnt)/len; if (isNegative) res *= 1.5; if (isEven) res *= 2; res *= 100; printf("%.2f%%", res);}笔记部分
printf()是格式化输出,前面的%.2f指的是以两位小数输出,后面的%%指的是输出一个%符号。printf()支持以下几种格式说明符:%d(有符号十进制整数)%f(浮点数)%s(字符串)%c(字符)%x(无符号十六进制整数)。- 类似的格式说明符也可以用于输入
scanf()。 - C++17中检测
string中是否含有某字符需要通过string.find()来完成。具体地,应为s.find()!=string::npo,表示找到的位置不是npos,即该位置存在。可以通过该方法来查询string中是否出现了负号来判断是否为负数。当然,在本段代码中采用的是isdigit(content[0])来判断是否有负号。
L1-018
代码部分
#include <bits/stdc++.h>using namespace std;typedef long long ll;
void solve(const string& content);
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); string time; cin>>time; solve(time); return 0;}
void solve(const string& content) { const string a = content.substr(0,2); const string b = content.substr(3,2); const int h = stoi(a); if (h<12||(h==12&&b=="00")) cout<<"Only "<<content<<". Too early to Dang."; else { const int time = stoi(a)-12+(b=="00"?0:1); for (int i = 1; i <= time; i++) cout<<"Dang"; }}笔记部分
stoi()只能用于string转int的情况。- 【便于记忆】索引是位于字符串中的
char之间的。比方说,以string s = "time"为例,其索引为0t 1i 2m 3e。其中,从0开始长度为2即代表0 1 2中的char,即为ti。
L1-019
代码部分
#include <bits/stdc++.h>using namespace std;typedef long long ll;
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int AMax, BMax, time; cin>>AMax>>BMax>>time; int curtA = 0, curtB = 0; for (int i = 1; i <= time; i++) { int num[4]; cin >> num[0] >> num[1] >> num[2] >> num[3]; const int sum = num[0] + num[2]; if (num[1]==sum&&num[3]!=sum) curtA++; if (num[1]!=sum&&num[3]==sum) curtB++; bool isADefeated = curtA == AMax + 1; if (isADefeated || curtB == BMax + 1) { cout<<(isADefeated?"A":"B")<<"\n"<<(isADefeated?curtB:curtA); return 0; } } return 0;}笔记部分
- 这里出现了连续定义的两种形式: ①未初始化的定义
int AMax, BMax, time;,此处三个值均未被初始化; ②初始化的定义int curtA = 0, curt B = 0;,此处两个值均被初始化为0。 - 特别地,考虑以下的情况: ①
int& a,b;这种情况应为int &a; int b;; ②int a,b = 1;这种情况应为`int a; int b = 1;。 - 为处理上一条中的②,我们可以采用C++的链式赋值,即你可以这么操作
a=b=1。具体地,在链式赋值中,编译器首先会从最右端开始分组。计算(b=1)后返回b的引用,进而让a= (b=1),使得a=1。 cin可连续赋值,如cin >> num[0] >> num[1] >> num[2] >> num[3];所示。不过这一点在cout中其实已经用到过了,如之前的cout<<"Only "<<content<<". Too early to Dang."就是连续传入给cout的。
L1-020
代码部分
#include <bits/stdc++.h>using namespace std;typedef long long ll;
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int N; cin>>N; set<string> s; for (int i = 1; i <= N; i++) { int K; cin>>K; for (int j = 1; j <= K; j++) { string temp; cin>>temp; if (K>1) s.insert(temp); } } int M; cin>>M; set<string> res; bool isFirst = false; for (int i = 1; i <= M; i++) { string M1; cin>>M1; if ((s.count(M1)==0)&&res.count(M1)==0) { if (isFirst) cout<<" "; isFirst = true; cout<<M1; res.insert(M1); } } if (res.empty()) cout<<"No one is handsome"; return 0;}笔记部分
- C++中的
set也要求不能出现重复元素,但multiset可以出现重复元素。将元素加入set的方法为set.insert()。 - C++17中没有直接检测
set中是否存在某元素的方法,只能通过set.count()检查元素出现的次数来曲线救国。
L1-016~L1-020的笔记
https://samera2022.github.io/posts/Notes/GPLT/l1-016l1-020/