1497 字
7 分钟
L1-016~L1-020的笔记
Samera2022
/
GPLTNotes
Waiting for api.github.com...
00K
0K
0K
Waiting...

P.S. 这份笔记同步发布在我的博客上,建议在博客中查看以享受完整的MD Extended Features. 你可以点此快速跳转到相应页面,我的博客地址为https://samera2022.github.io

L1-016#

代码部分#

L1-016.cpp
#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#

代码部分#

L1-017.cpp
#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#

代码部分#

L1-018.cpp
#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()只能用于stringint的情况。
  • 【便于记忆】索引是位于字符串中的char之间的。比方说,以string s = "time"为例,其索引为0t 1i 2m 3e。其中,从0开始长度为2即代表0 1 2中的char,即为ti

L1-019#

代码部分#

L1-019.cpp
#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#

代码部分#

L1-020.cpp
#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/
作者
Samera2022
发布于
2026-01-22
许可协议
CC BY-NC-SA 4.0