c++程序题输入及处理总结(自用)
·
不同程序题有不同的输入格式:
目录
5.第一行输入一个由字母、数字和空格组成的字符串,第二行输入一个字符(保证该字符不为空格)
1.输入一行成组数据,输入多少组不定,成组数据间有特殊字符
例子:幼儿园分班问题
输入:1/N 2/Y 3/N 4/Y
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <set>
using namespace std;
struct Child {
int id;
char flag;
};
int main() {
string input;
getline(cin, input);
stringstream ss(input);
vector<Child> children;
string token;
// 解析输入
while (ss >> token) {
//ss >> token 会从流中读取一个以空格分隔的字符串到 token 中
size_t pos = token.find('/');
//token.find('/') 在字符串 token 中查找字符 '/' 的位置
if (pos == string::npos) {
//size_t 是一种无符号整数类型,专门用于表示大小和位置
//string::npos 是一个特殊常量,表示"未找到"或"无效位置"
//它的值通常是 -1(但实际类型是 size_t 的最大值)
//如果 find() 没有找到指定的字符,就返回 string::npos
cout << "ERROR" << endl;
return 0;
}
string idStr = token.substr(0, pos);
char flag = token[pos+1];
int id = stoi(idStr);
if (id <= 0 || id > 999) {
cout << "ERROR" << endl;
return 0;
}
if (flag != 'Y' && flag != 'N') {
cout << "ERROR" << endl;
return 0;
}
children.push_back({id, flag});
}
int n = children.size();
if (n == 0) {
cout << "ERROR" << endl;
return 0;
}
vector<int> classId(n, -1); // 记录每个小朋友的班级:0或1
classId[0] = 0; // 第一个小朋友默认分到班级0
for (int i = 1; i < n; i++) {
if (children[i].flag == 'Y') {
classId[i] = classId[i-1];
} else { // 'N'
classId[i] = 1 - classId[i-1];
}
}
// 检查是否有矛盾:遍历每个小朋友(从第二个开始),验证标记是否与分班一致
for (int i = 1; i < n; i++) {
if (children[i].flag == 'Y') {
if (classId[i] != classId[i-1]) {
cout << "ERROR" << endl;
return 0;
}
} else {
if (classId[i] == classId[i-1]) {
cout << "ERROR" << endl;
return 0;
}
}
}
// 收集两个班级的小朋友编号
set<int> class0, class1;
for (int i = 0; i < n; i++) {
if (classId[i] == 0) {
class0.insert(children[i].id);
} else {
class1.insert(children[i].id);
}
}
// 输出
if (!class0.empty()) {
for (auto it = class0.begin(); it != class0.end(); it++) {
if (it != class0.begin()) cout << " ";
cout << *it;
}
cout << endl;
}
if (!class1.empty()) {
for (auto it = class1.begin(); it != class1.end(); it++) {
if (it != class1.begin()) cout << " ";
cout << *it;
}
cout << endl;
} else {
cout << endl; // 第二行为空
}
return 0;
}
2.输入:第一行 不确定个数的数字,第二行一个数字
/*在一个狭小的路口,每秒只能通过一辆车,假好车辆的颜色只有 3 种,找出 N 秒内经过的最多颜色的车辆数量。
三种颜色编号为0 ,1 ,2
输入描述
第一行输入的是通过的车辆颜色信息[0,1,1,2] 代表4 秒钟通过的车辆颜色分别是 0 , 1 , 1 , 2
第二行输入的是统计时间窗,整型,单位为秒
输出描述
输出指定时间窗内经过的最多颜色的车辆数量。
样例
样例一:
输入
0 1 2 1
3
输出
2
样例解释
在 3 秒时间窗内,每个颜色最多出现 2 次。例为:[1,2,1]
样例二:
输入
0 1 2 1
2
输出
1
样例解释
在 2 秒时间窗内,每个颜色最多出现1 次。*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> colors;
int num;
while (cin >> num) {
colors.push_back(num);
if (cin.peek() == '\n') break;
}
int windowSize;
cin >> windowSize;
int count[3] = {0};
int maxCount = 0;
int n = colors.size();
for (int i = 0; i < n; i++) {
count[colors[i]]++;
if (i >= windowSize) {
count[colors[i - windowSize]]--;
}
int currentMax = max({count[0], count[1], count[2]});
if (currentMax > maxCount) {
maxCount = currentMax;
}
}
cout << maxCount << endl;
return 0;
}
/*爱吃蟠桃的孙悟空
题目描述:
孙悟空喜欢吃蟠桃,一天他乘守卫蟠桃园的天兵天将离开了而偷偷的来到王母娘娘的蟠桃园偷吃蟠桃。
已知蟠桃园有 N 棵蟠桃树,第 i 棵蟠桃树上有 N[i](大于 0)个蟠桃,天兵天将将在 H(不小于蟠桃树棵数)小时后回来。
孙悟空可以决定他吃蟠桃的速度 K(单位:个/小时),每个小时他会选择一颗蟠桃树,从中吃掉 K 个蟠桃,
如果这棵树上的蟠桃数小于 K,
他将吃掉这棵树上所有蟠桃,然后这一小时内不再吃其余蟠桃树上的蟠桃。
孙悟空喜欢慢慢吃,但仍想在天兵天将回来前将所有蟠桃吃完。
求孙悟空可以在 H 小时内吃掉所有蟠桃的最小速度 K(K 为整数)。
输入描述:
从标准输入中读取两行数字,第一行数字表示每棵数上蟠桃个数,第二行的数字表示天兵天将将离开的时间。
输出描述:
吃掉所有蟠桃的 最小速度 K(K 为整数)或 输入异常时输出 -1。
示例 1:
输入
3 11 6 7
8
输出
4
说明:
天兵天将8个小时后回来,孙悟空吃掉所有蟠桃的最小速度4。
第1小时全部吃完第一棵树,吃3个,
第2小时吃4个,第二棵树剩7个,
第3小时吃4个,第二棵树剩3个,
第4小时吃3个,第二棵树吃完,
第5小时吃4个,第三棵树剩2个,
第6小时吃2个,第三棵树吃完,
第7小时吃4个,第4棵树剩3个,
第8小时吃3个,第4棵树吃完。
*/
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <cmath>
using namespace std;
// 计算以速度k吃完所有桃子需要的时间
long long calculateTime(const vector<int>& piles, int k) {
long long time = 0;
for (int pile : piles) {
time += (pile + k - 1) / k; // 等价于 ceil(pile / k)巧妙的整数除法向上取整的方法
}
//整数向上取整的技巧:公式: ⌈a / b⌉ = (a + b - 1) / b
return time;
}
int main() {
string line1, line2;
// 读取第一行(桃子数)
if (!getline(cin, line1)) {
cout << -1 << endl;
return 0;
}
// 读取第二行(时间H)
if (!getline(cin, line2)) {
cout << -1 << endl;
return 0;
}
// 解析桃子数
vector<int> piles;
stringstream ss1(line1);
int num;
while (ss1 >> num) {//*********
if (num <= 0) {
cout << -1 << endl;
return 0;
}
piles.push_back(num);
}
// 解析时间H
stringstream ss2(line2);
int H;
if (!(ss2 >> H) || H <= 0) {//
cout << -1 << endl;
return 0;
}
// 检查H是否小于树的数量
if (H < piles.size()) {
cout << -1 << endl;
return 0;
}
// 二分查找
int left = 1;
int right = *max_element(piles.begin(), piles.end());//头文件是<algorithm>
int result = right;
while (left <= right) {
int mid = left + (right - left) / 2;
long long timeNeeded = calculateTime(piles, mid);
if (timeNeeded <= H) {//H时间
result = mid; // 当前速度可行,尝试更小的速度
right = mid - 1;
} else {
left = mid + 1; // 当前速度太慢,需要更大的速度
}
}
cout << result << endl;
return 0;
}
3.输入一组不定个数的数字
/*有一个荒岛,只有左右两个港口,只有一座桥连接这两个港口,现在有一群人需要从两个港口逃生,有的人往右逃生,有的往左逃生,
如果两个人相遇,则PK,体力值大的能够打赢体力值小的,体力值相同则同归干尽,赢的人才能继续往前逃生,并减少相应的体力
输入描述
一行非 0 整数,用空格隔开,正数代表向右逃生,负数代表向左逃生
输出描述
最终能够逃生的人数
示例1:
输入
5 10 8 -8 -5
输出
2
说明
8与-8 相遇,同归于尽,10 遇到-5,打赢并减少五点体力,最终逃生的为5,5,均从右侧港口逃生,输出2*/
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> people;
int num;
while (cin >> num) {
people.push_back(num);
}
int n = people.size();
vector<int> state = people;
// 第一遍:处理向右逃生的人(遇到后面的向左逃生的人)
for (int i = 0; i < n; i++) {
if (state[i] > 0) {
int right_strength = state[i];
for (int j = i + 1; j < n && right_strength > 0; j++) {
if (state[j] < 0) {
int left_strength = -state[j];
if (right_strength > left_strength) {
right_strength -= left_strength;
state[j] = 0;
} else if (right_strength < left_strength) {
state[j] = -(left_strength - right_strength);
right_strength = 0;
} else {
state[j] = 0;
right_strength = 0;
}
}
}
state[i] = right_strength;
}
}
// 第二遍:处理剩余的向左逃生的人(确保最左边的向左逃生的人也被处理)
for (int i = n - 1; i >= 0; i--) {
if (state[i] < 0) {
int left_strength = -state[i];
for (int j = i - 1; j >= 0 && left_strength > 0; j--) {
if (state[j] > 0) {
if (left_strength > state[j]) {
left_strength -= state[j];
state[j] = 0;
} else if (left_strength < state[j]) {
state[j] -= left_strength;
left_strength = 0;
} else {
state[j] = 0;
left_strength = 0;
}
}
}
state[i] = left_strength > 0 ? -left_strength : 0;
}
}
// 统计结果
int result = 0;
for (int i = 0; i < n; i++) {
if (state[i] != 0) {
result++;
}
}
cout << result << endl;
return 0;
}
/*民警办案*/
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
using namespace std;
int findMajority(vector<int>& men) {
if (men.empty()) return 0;
int candidate = -1;
int count = 0;
for (int num : men) {
if (count == 0) {
candidate = num;
count = 1;
} else {
if (num == candidate) {
count++;
} else {
count--;
}
}
}
count = 0;
for (int num : men) {
if (num == candidate) {
count++;
}
}
int n = men.size();
if (count > n / 2) {
return candidate;
} else {
return 0;
}
}
int main() {
string line;
getline(cin, line);
vector<int> men;
stringstream ss(line);
int num;
while (ss >> num) {
men.push_back(num);
}
int result = findMajority(men);
cout << result << endl;
return 0;
}
4.(处理)输入n组不确定个数的数字
/*民警办案:处理n数据*/
int main() {
int n;
cin >> n; // 读取数据组数
cin.ignore(); // 忽略换行符
vector<int> results;
for (int i = 0; i < n; i++) {
string line;
getline(cin, line); // 读取一行数据
vector<int> men;
stringstream ss(line);
int num;
while (ss >> num) {
men.push_back(num);
}
int result = findMajority(men);
results.push_back(result);
}
// 输出所有结果
for (int result : results) {
cout << result << endl;
}
return 0;
}
5.第一行输入一个由字母、数字和空格组成的字符串,第二行输入一个字符(保证该字符不为空格)
/*写出一个程序,接受一个由字母、数字和空格组成的字符串,
和一个字符,然后输出 "输入字符串" 中该字符的出现次数。
(不区分大小写字母)。
输入描述
第一行输入一个由字母、数字和空格组成的字符串,
第二行输入一个字符(保证该字符不为空格)。
输出描述
输出输入字符串中含有该字符的个数,(不区分大小写字母)
示例1
输入
Hello World
o
输出
2*/
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string inputStr;
char targetChar;
// 读取第一行字符串
getline(cin, inputStr);//cin遇到空格就停止
// 读取第二行字符
cin >> targetChar;
// 将目标字符转换为小写
char lowerTargetChar = tolower(targetChar);
int count = 0;
// 遍历字符串中的每个字符
for (char c : inputStr) {
// 将当前字符转换为小写后比较
if (tolower(c) == lowerTargetChar||) {
count++;
}
}
cout << count << endl;
return 0;
}
6.处理一个需以特殊字符分段的字符串
例如:/abc/,/bcd,解题过程中需要提取,前后两段
/*题目描述: 给定一个url前缀和url后缀,通过,分割 需要将其连接为一个完整的url 如果前缀结尾和后缀开头都没有/,需要自动补上/连接符 如果前缀结尾和后缀开头都为/,需要自动去重 约束:不用考虑前后缀URL不合法情况
输入描述: url前缀(一个长度小于100的字符串) url后缀(一个长度小于100的字符串)
输出描述: 拼接后的url
示例 1:
输入 /acm,/bb 输出 /acm/bb
示例 2:
输入 /abc/,/bcd 输出 /abc/bcd
示例 3:
输入 /acd,bef 输出 /acd/bef
示例 4:
输入 , 输出 /
*/
#include <iostream>
#include <string>
using namespace std;
int main() {
string input;
getline(cin, input);
size_t pos = input.find(',');
string prefix = input.substr(0, pos);
string suffix = input.substr(pos + 1);
//substr() 函数的基本用法
//string.substr(pos):返回从位置 pos 开始到字符串末尾的子字符串
//string.substr(pos, count):返回从位置 pos 开始,长度为 count 的子字符串
if (prefix.empty() && suffix.empty()) {
cout << "/" << endl;
return 0;
}
if (!prefix.empty() && !suffix.empty()) {
if (prefix.back() == '/' && suffix.front() == '/') {
suffix = suffix.substr(1);
} else if (prefix.back() != '/' && suffix.front() != '/') {
prefix += '/';
}
} else if (!prefix.empty() && prefix.back() != '/') {
prefix += '/';
} else if (!suffix.empty() && suffix.front() != '/') {
suffix = '/' + suffix;
}
cout << prefix + suffix << endl;
return 0;
}
更多推荐


所有评论(0)