第一章
1-1.最大因子
【问题描述】
给定一组共n(1≤n≤5000)个整数,整数的取值范围为1到20000,请确定具有最大素数因子的整数(请记住,素数只有因子1和自身,整数7是素数,而整数6可以被2和3整除,它不是素数)。
【输入形式】
第一行为单个整数n,接下来共n个整数,每行包含一个整数。
【输出形式】
在一行中输出具有最大素数因子的那个整数,如果有多个,则输出最早出现在输入文件中的一个。
【样例输入】
4
36
38
40
42
【样例输出】
38
【样例说明】
测试数据的文件名为in.txt
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream input;
input.open("in.txt");
int n;
int num;
int max = 0;
int ans = 0;
string str;
getline(input, str);
n = stoi(str); //获取数字个数
while (n > 0) { //读取数据
getline(input, str);
num = stoi(str);
int k = 2;
int numcpy = num;
if (num == 1) {
k = 1;
}
while (num > 1) { //求数据的最大素因子
if (num % k == 0) {
num = num / k;
} else {
k++;
}
}
if (k > max) { //如果大于最大值,答案为此数字
max = k;
ans = numcpy;
}
n--;
}
cout << ans;
return 0;
}
1-2.回文数
【问题描述】
判断一个整数是否是回文数。例如,121是回文数,而-121不是回文数。
【输入形式】
每个测试用例输入一行,是一个整数。
【输出形式】
对于每个测试用例输出一行,输出0表示不是回文数,或者输出1表示是回文数。
【样例输入】
12345
【样例输出】
0
【样例说明】
测试用例中的每一行代表一个待测试的整数,测试数据的文件名为in.txt。
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream input;
input.open("in.txt");
string str;
getline(input, str);
int n = stoi(str);
int ncpy = n;
int b = -1;
int i = 0;
if (n < 0) {
cout << 0;
return 0;
}
while (ncpy != 0) { //算出n的位数,赋值于b
ncpy = ncpy / 10;
b++;
}
while (i < b) {
int high = n;
int low = n;
for (int bcpy = b; bcpy > 0; bcpy--) { //求高位数字
high = high / 10;
}
for (int icpy = i; icpy > 0; icpy--) { //求低位数字
low = low / 10;
}
if (high % 10 != low % 10) { //判断是否相等
cout << 0;
return 0;
}
i++;
b--;
}
cout << 1;
return 0;
}
第二章
2-1.集合并集运算
【问题描述】
给你两个集合A和B,要求{A}+{B}。注意同一个集合中不会有两个相同的元素。
【输入形式】
每组输入数据分为三行,第一行有两个数字n,m(0<n,m≤10000),分别表示集合A和集合B的元素个数。后两行分别表示集合A和集合B,每个元素为不超出int范围的整数,两个元素之间有一个空格隔开。
【输出形式】
针对每组数据输出一行数据,表示合并后的集合,要求从小到大输出,两个元素之间有一个空格隔开。
【样例输入】
1 2
1
2 3
【样例输出】
1 2 3
【样例说明】
第一行的两个数字表示集合A和集合B的元素个数,后面两行分别表示集合A和集合B中的整数元素,两个元素之间用空格隔开。测试数据存放在in.txt文件中。
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <set>
using namespace std;
int main() {
ifstream input;
input.open("in.txt");
set<int> s; //集合并集,直接使用集合
string line;
string data;
getline(input, line);
while (getline(input, line)) {
istringstream iss(line);
while (iss >> data) { //分行输入,不存在则添加
if (s.find(stoi(data)) == s.end()) {
s.insert(stoi(data));
}
}
}
for (set<int>::iterator it = s.begin(); it != s.end(); it++) { //遍历输出
cout << *it << " ";
}
return 0;
}
2-2.重排链表
【问题描述】
假设不带头结点的单链表结点类型如下:
struct ListNode
{ int val;
ListNode *next;
ListNode(int x):val(x),next(NULL){}
};
给定一个含n+1个结点的单链表L:L0→L1→…→Ln-1→Ln,将其重新排列后变为:L0→Ln→L1→Ln-1→L2→Ln-2→…。你不能只是单纯的改变结点内部的值,而是需要实际的进行结点交换。示例1,给定链表为1->2->3->4,重新排列为1->4->2->3。示例2,给定链表为1->2->3->4->5,重新排列为1->5->2->4->3。你需要设计的reorderList函数。
【输入形式】
输入含有n个元素的单链表。
【输出形式】
输出重排后的单链表中的元素。
【样例输入】
1 2 3 4
【样例输出】
1 4 2 3
【样例说明】
输入文件名为in.txt。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode() : val(0), next(NULL) {}
ListNode(int x) : val(x), next(NULL) {}
};
class Solution
{
public:
ListNode *reorderList(ListNode *head) //重排链表
{
vector<int> vec;
vector<int> vec2;
ListNode *headcpy = head;
while (head != NULL) //根据传入链表构建数组
{
vec.push_back(head->val);
head = head->next;
}
delete headcpy;
for (int i = 0, j = vec.size() - 1; i <= j; i++, j--) //重排数组
{
vec2.push_back(vec[i]);
vec2.push_back(vec[j]);
if (i == j)
{
vec2.pop_back();
}
}
return buildList(vec2); //根据重排后数组再次构建链表
}
ListNode *buildList(vector<int> vec) //传入数组,构建链表,返回链表头结点
{
ListNode *pre = NULL;
for (vector<int>::reverse_iterator rit = vec.rbegin(); rit != vec.rend(); rit++)
{
ListNode *node = new ListNode();
node->val = *rit;
node->next = pre;
pre = node;
}
return pre;
}
};
int main()
{
Solution solution = Solution();
ifstream input;
input.open("in.txt");
string data;
vector<int> vec;
while (input >> data)
{
vec.push_back(stoi(data));
}
ListNode*pre=solution.buildList(vec);
pre = solution.reorderList(pre);
while (pre != NULL) //遍历链表
{
cout << pre->val << " ";
pre = pre->next;
}
return 0;
}
第三章
3-1.晒黑沙龙
【问题描述】
有一个Tan Your Hide的公司拥有数家投币式晒黑沙龙。研究表明,如果客户到达而没有可用的床位,则客户可能会转身离开,从而使公司损失一笔销售费用。你的任务是编写一个程序告诉公司有多少客户不晒黑就离开了。
【输入形式】
输入内容包含一个沙龙数据,该沙龙的数据是一行,其中包含一个正整数,代表沙龙中的日光浴床数量,后跟一个空格,然后是一个大写字母序列,序列中的字母是成对出现的,第一次出现表示该客户的到来,第二次出现表示同一客户的离开,不会出现超过一对的字母。没有晒黑就离开的客户总是先于当前晒黑的客户离开。每个沙龙最多可容纳20张床。
【输出形式】
对于每个沙龙,输出一个句子,告诉有多少顾客走了,使用样例显示的确切格式。比如,若有2个顾客走了,则输出2 customer(s) walked away. 若没有顾客离开,则输出All customers tanned successfully.
【样例输入】
1 ABCBCA
【样例输出】
2 customer(s) walked away.
【样例说明】
2代表沙龙中有两张床,ABC等字母代表单个人,第1次出现代表入住,第2次出现代表离开。上述样例的处理过程如下:
① A入住
② B入住,入住失败
③ C入住,入住失败
④ B离开,共1人离开(未住店)
⑤ C离开,共2人离开(未住店)
⑥ A离开
结果是“2 customer(s) walked away.”。
测试数据存放在in.txt文件中。
#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include <queue>
using namespace std;
int main() {
ifstream input;
input.open("in.txt");
set<char> s; //使用中顾客集合
set<char> waits; //等待中顾客集合
queue<char> wait; //排队等待队列
int count = 0; //没晒黑就离开的顾客数量
string line;
int num;
char data;
input >> num; //读取浴床数量
while (input >> data) { //读取顾客
if (s.find(data) != s.end()) { //如果顾客在使用,则顾客离开
s.erase(data); //等待队列首位如果仍在等待集合中,则使用
while (!wait.empty() && waits.find(wait.front()) == waits.end()) {
wait.pop(); //否则不断弹出
}
if (!wait.empty()) { //找到未离开的队列首位,进入使用,并出队
waits.erase(wait.front());
s.insert(wait.front());
wait.pop();
}
} else { //如果顾客在等待,则顾客离开,离开人数加一
if (waits.find(data) != waits.end()) {
count++;
waits.erase(data); //从等待集合中删除
} else {
if (s.size() >= num) { //如果使用人数已满,加入等待集合和队列中
waits.insert(data);
wait.push(data);
} else { //未满则直接使用
s.insert(data);
}
}
}
}
if (count > 0) { //输出未晒黑就离开人数
cout << count << " customer(s) walked away." << endl;
} else {
cout << "All customers tanned successfully." << endl;
}
return 0;
}
3-2.两数之和
【问题描述】
给定一个整数数组nums和一个目标值target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。例如,给定nums=[2,7,11,15],target=9,返回结果为[0,1]。若没有答案,则返回[-1,-1]。
【输入形式】
每个测试用例由两行数据构成,第一行给出整数数组,元素之间以空格隔开,可以有重复元素;第二行给出求和的目标值。
【输出形式】
返回累加和为目标值的两个整数在数组中的下标值,不限顺序。若没有答案,则返回[-1,-1]。
【样例输入】
2 7 11 15
9
【样例输出】
0 1
【样例说明】
输入的整数数组有四个整数,分别为2,7,11,15,目标值为9。数组中的2和7的累加和为9,因此返回这两个整数在数组中的下标地址,即0,1。测试数据文件名为in.txt。
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
vector<int> twoSum(vector<int> vec, int target) {
vector<int> ans; //答案数组
unordered_map<int, int> map;
for (int i = 0; i < vec.size(); i++) {
if (map.find(target - vec[i]) != map.end()) { //查找map
ans.push_back(map[target - vec[i]]); //存在则数组加入两数下标
ans.push_back(i);
return ans;
}
map.insert(pair<int, int>(vec[i], i)); //数组元素按<数值,下标>入map
}
ans.push_back(-1); //否则输出[-1,-1]
ans.push_back(-1);
return ans;
}
};
int main() {
Solution solution = Solution();
ifstream input;
input.open("in.txt");
vector<int> vec;
string line;
string data;
getline(input, line);
istringstream iss(line);
while (iss >> data) { //根据输入构建数组
vec.push_back(stoi(data));
}
getline(input, line);
int target = stoi(line); //获取目标值
vector<int> ans = solution.twoSum(vec,target);
for (vector<int>::iterator it = ans.begin(); it != ans.end(); it++) {
cout << *it << " ";
}
}