1824 字
9 分钟
L1-006~L1-010的笔记
Samera2022
/
GPLTNotes
Waiting for api.github.com...
00K
0K
0K
Waiting...

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

L1-006#

代码部分#

L1-006.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//Spec A 2/20 Point
void solve(int N);
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int N;
cin>>N;
solve(N);
return 0;
}
void solve(const int N) {
//Spec Tip Start
int crtMax = 1;//连续因数的个数的最大值
int crt = N;//连续因数最小值,当其为质数时即为其本身
//Spec Tip End
for (int i = 2; i<=sqrt(N); i++) {
if (int n = N; n%i==0) {
int delta = 0;
bool valid = n%(i+delta)==0;
while (valid) {
n/=i+delta;
valid = n%(i+delta+1)==0;
if (valid) delta++;
else break;
}
//Spec Tip Start
//delta+1代表此时的连续因数长度,此时有更长连续因数长度时,对crt进行同步
if (delta+1>crtMax) {
crtMax = delta+1;
crt = i;
}
if (crt==N) crt = i;//需要最小因子序列,因此需要考虑其可分解为两数相乘时,连续因数最小值改为最小因数
//Spec Tip End
}
}
cout<<crtMax<<"\n";
for (int i = 0; i < crtMax; i++) {
cout<<crt+i;
if (i!=crtMax-1) cout<<"*";
}
}

笔记部分#

  • 没有什么好记的,这题主要是算法上稍微绕了一下。

L1-007#

代码部分#

L1-007.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(const string& s);
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
string s;
cin>>s;
solve(s);
return 0;
}
void solve(const string& s) {
string result;
int len = static_cast<int>(s.length());
for (int i = 0; i<len; i++) {
switch (s[i]) {
case '-':
result.append("fu");
break;
case '1':
result.append("yi");
break;
case '2':
result.append("er");
break;
case '3':
result.append("san");
break;
case '4':
result.append("si");
break;
case '5':
result.append("wu");
break;
case '6':
result.append("liu");
break;
case '7':
result.append("qi");
break;
case '8':
result.append("ba");
break;
case '9':
result.append("jiu");
break;
case '0':
result.append("ling");
break;
default:
break;
}
if (i!=len-1) result.append(" ");
}
cout<<result;
}

笔记部分#

  • 此处用到了C++风格的强制转型static_cast<int>(),Java中的写法(int)也能用,但是那被称为C风格的强制转型。
  • C++中的string可以像Java的StringBuilder一样使用append方法。更进一步地,C++的字符串可以直接编辑原处,而Java的字符串由于其不可变导致只能编辑副本,这使得C++的字符串更轻一些。
  • 也许有人会说为啥我写这么长的switch-case都不考虑直接单独处理符号再写个数组来处理0~9,究其根本, 我只能说我想试试C++中的switch-case和Java中是否一致))

L1-008#

代码部分#

L1-008.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//Spec A 2/10 Point
void solve(int A, int B);
void handle(int num);
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int A;
cin>>A;
int B;
cin>>B;
solve(A,B);
return 0;
}
void solve(const int A, const int B) {
const int total = B - A + 1;
const int time = total / 5;
for (int i = 1; i <= time; i++) {
for (int j = 1; j<=5; j++) handle(A+5*(i-1)+(j-1));
cout<<"\n";
}
//Spec Tip Start
if (const int rest = total % 5; rest!=0) {
for (int j = rest - 1; j >= 0; j--) handle(B-j);
cout<<"\n";
}
//Spec Tip End
cout<<"Sum = "<<((A+B)*total/2);
}
void handle(const int num) {
string s = to_string(num);
const int len = static_cast<int>(s.length());
const int lLen = 5 - len;
for (int i = 1; i <= lLen; i++) cout<<" ";
cout<<s;
}

笔记部分#

  • 此处的solve方法直接采用了值传递。我们可以发现,值传递时,方法参数的const与否不妨碍其声明中无需写const。声明中的引用传递的const主要是为了确保方法不会修改原来的值,而值传递的情况下修改后和原来也无所谓,所以声明中不能再写const修饰。

L1-009#

代码部分#

L1-009.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//Spec A 11/20 Point
pair<ll, ll> split(const string& s, char delimiter);
ll gcd(ll a, ll b);
void simplify(ll& a, ll& b);
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int N;
cin>>N;
ll curtNum = 0;
ll curtDen = 1;
for (ll i = 1; i <= N; i++) {
string content;
cin>>content;
const auto [Num, Den] = split(content,'/');
curtNum = curtNum*Den+curtDen*Num;
curtDen *= Den;
simplify(curtNum, curtDen);
}
const ll res = curtNum/curtDen;
ll resNum = curtNum%curtDen;
simplify(resNum,curtDen);
if (res==0&&resNum!=0) cout<<resNum<<"/"<<curtDen;
if (res!=0&&resNum==0) cout<<res;
if (res!=0&&resNum!=0) cout<<res<<" "<<resNum<<"/"<<curtDen;
if (res==0&&resNum==0) cout<<0;
return 0;
}
pair<ll,ll> split(const string& s, const char delimiter) {
pair<ll,ll> tokens;
if (s.find(string(1,delimiter))!=string::npos) {
string token;
stringstream ss(s);
getline(ss,token, delimiter);
tokens.first = stoll(token);
getline(ss, token, delimiter);
tokens.second = stoll(token);
} else {
tokens.first = stoll(s);
tokens.second = 1;
}
return tokens;
}
ll gcd(ll a, ll b) {
while (b != 0) {
a %= b;
swap(a, b);
}
return a;
}
void simplify(ll& a, ll& b) {
const ll multiplier = gcd(a,b);
a /= multiplier;
b /= multiplier;
}

笔记部分#

  • 我原来写的是先乘出完整的分母,再算出完整的分子,最后直接约分得到结果,但是这题有个小分值的测试点会超long long的范围,导致只能逐步约分了。
  • 也许有人会说为什么我要连着写四个if而不用if else-if else,再或者在每个if的结构体中直接return 0;。究其根本,我只能说这是对称美)))言归正传,这确实会损失少量性能,不过我还是觉得这很美观))
  • 本题中可能出现负数,在实际操作中求最大公约数(gcd)是可以正常处理负数的,但是返回的结果可能需要进一步的操作。因而我直接采用了绝对值计算,这会保险一些。
  • 另记:有人可能会采用递归写法的gcd,需要补充的是,在递归深度达到1e5或1e6时,递归可能导致栈溢出(Stack Overflow),而循环则不会出现这种问题。此外,递归涉及调用、压栈、弹栈、参数传递等CPU操作,这也使得其常数时间通常比循环要大。
  • C++中没有现成的split方法,需要你手动进行实现……因此,我们需要清楚getline()的具体作用:首先需要指出的是,这是getline()函数的其中一个作用,另外一个作用等到下一次见到它的时候再说。该函数有三个参数,此处我们填入的是(stringstream, string, char)getline首先会清空string中原有的内容,而后从stringstream中逐个读取字符,一直读取到char出现时停止读取,此时会将读取到的char之前的字符串存入你提供的string中。如果不填入char,则其会默认读到行末换行(不包含换行符)。由于内容会被存入string,这使得你只能传入左值(L-Value)进去。在这种情况下,getline起到的实际上是字符分割的作用。
  • 另记:左值(L-Value)是一个正常的变量,你可以通过变量名来访问它。右值(R-Value)是一个临时变量,你无法通过变量名来访问它(因为它不存在变量名)。比方说,to_string(num)是一个匿名返回值,你无法用一个变量名来访问它;"42"是一个字面量,你也无法用一个变量名来访问它。这些变量在所在行结束后就会被销毁,因而被算作右值(R-Value)。简单地说,你可以通过“是否有一个变量名”来快速判断左右值。

L1-010#

代码部分#

L1-010.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 A,B,C = 0;
cin>>A;
cin>>B;
cin>>C;
vector v = {A,B,C};
sort(v.begin(), v.end());
for (int i = 1; i <= 3; i++) {
cout<<v[i-1];
if (i!=3) cout<<"->";
}
return 0;
}

笔记部分#

  • 一个比大小的题目,可以用if-else来判断得到排序结果。这里我懒了一下,直接用数组排序了。
  • C++的vector和Java的ArrayList性质相似,但是在查询元素位置的时候,如果你使用vector.at(i),其会因为越界检查而比vector[i]要更慢。
L1-006~L1-010的笔记
https://samera2022.github.io/posts/Notes/GPLT/l1-006l1-010/
作者
Samera2022
发布于
2026-01-22
许可协议
CC BY-NC-SA 4.0