合数是指大于1的自然数,除了1和它本身外,还能被其他自然数整除的数。例如4可以被1、2、4整除,所以4是合数;而3只能被1和3整除,所以3不是合数。
纯粹合数则是一个更严格的概念:一个合数,如果去掉它的最高位后剩下的数是0或仍是合数,并且这个性质在逐步去掉最高位的过程中始终保持,直到最后剩下的一位数仍是0或合数,那么这个数就是纯粹合数。
注意:在判断过程中,前置的0会被忽略。例如100去掉最高位1后剩下00,会被视为0。
判断一个数是否为纯粹合数需要分两步:
cpp复制bool isHeShu(int n) {
if (n <= 1) return false;
for (int i = 2; i <= n/2; i++) {
if (n % i == 0)
return true;
}
return false;
}
bool isChunCui(int n) {
while (n > 0) {
if (!isHeShu(n) && n != 0)
return false;
int bei = n / pow(10, to_string(n).length()-1);
n -= bei * pow(10, to_string(n).length()-1);
}
return true;
}
我们可以从100开始逐个检查每个数是否是纯粹合数,直到找到足够数量的纯粹合数:
cpp复制vector<int> heshu;
int x = 100;
while (heshu.size() < 100) {
if (isChunCui(x)) {
heshu.push_back(x);
}
x++;
}
to_string(num).length()快速获取数字位数是个好方法i<=n/2不能写成i<n/2,否则会漏判像4这样的数给定一个数字串,找出其中长度不超过4的最长子串,使得这个子串表示的数是质数。如果有多个这样的子串,选择数值最大的一个。
质数是大于等于2且只能被1和自身整除的数。判断一个数是否为质数的基本算法:
cpp复制bool isPrime(int n) {
if (n == 0 || n == 1)
return false;
for (int i = 2; i <= n/2; i++) {
if (n % i == 0)
return false;
}
return true;
}
cpp复制string s;
while (cin >> s) {
int len = s.size() < 4 ? s.size() : 4;
vector<int> subs_prime;
while (subs_prime.empty()) {
for (int i = 0; i+len <= s.size(); i++) {
int subNum = stoi(s.substr(i, len));
if (isPrime(subNum)) {
subs_prime.push_back(subNum);
}
}
len--;
}
cout << *max_element(subs_prime.begin(), subs_prime.end()) << endl;
}
s.substr(start, length)用于提取子串,stoi()将字符串转为整数max_element算法可以方便地找到容器中的最大值翻译规则如下:
例如:"2d352d@"的翻译过程:
cpp复制string s;
while (cin >> s) {
bool flag = false; // 标记前一个字符是否是数字
int cnt = 0;
int len = 0;
for (int i = 0; i < s.size(); i++) {
if (flag) {
for (int j = 0; j < cnt; j++) {
if (len % 3 == 0 && len != 0)
cout << " ";
cout << s[i];
len++;
}
flag = false;
}
else {
if (s[i] >= '0' && s[i] <= '9') {
flag = true;
cnt = s[i] - '0' + 1;
}
else {
if (len % 3 == 0 && len != 0)
cout << " ";
cout << s[i];
len++;
}
}
}
cout << endl;
}
s[i] - '0'将输入的数字串中的所有'5'视为分隔符,将字符串分割为多个数字(可能包含前导零),然后对这些数字进行排序输出。
cpp复制string s;
cin >> s;
vector<vector<int>> nums;
nums.push_back({});
for (int j = 0; j < s.size(); j++) {
if (s[j] == '5') {
nums.push_back({});
}
else {
nums.back().push_back(s[j] - '0');
}
}
vector<int> ans;
for (int j = 0; j < nums.size(); j++) {
int current_num = 0;
for (int k = 0; k < nums[j].size(); k++) {
current_num += nums[j][k] * pow(10, nums[j].size() - k - 1);
}
if (!nums[j].empty())
ans.push_back(current_num);
}
sort(ans.begin(), ans.end());
比较两个非负实数是否相等,考虑前导零和末尾零不影响数值大小。
使用stod函数将字符串转换为double类型,直接比较数值:
cpp复制string line;
getline(cin, line);
stringstream ss(line);
string s;
vector<string> a;
while (ss >> s) {
a.push_back(s);
}
if (stod(a[0]) == stod(a[1]))
cout << "YES" << endl;
else
cout << "NO" << endl;
stringstream处理可能包含空格的一行输入stod会自动忽略数字前面的零cin.ignore()清除缓冲区,避免getline读取残留的换行符在实际编程问题解决中,理解问题描述、设计算法、编写代码和测试调试是四个关键步骤。每个步骤都需要仔细思考和验证,特别是边界条件的处理往往决定了程序的健壮性。通过解决这些编程问题,可以锻炼逻辑思维能力和编程实践能力。