6.5 queue队列
问题 A: C语言-数字交换
问题描述:输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写三个函数; ①输入10个数;②进行处理;③输出10个数。
- 输入
10个整数
- 输出
整理后的十个数,每个数后跟一个空格(注意最后一个数后也有空格)
- 样例输入
2 1 3 4 5 6 7 8 10 9
- 样例输出
1 2 3 4 5 6 7 8 9 10
这题用数组就可以解决哇,不知道为啥按在这
#define _CRT_SECURE_NO_WARNINGS 1
#include <cstdio>
#include <string>
#include <iostream>
#include <map>
#include<queue>
using namespace std;
int main()
{
int a[10];
int i, max, min;
int temp;
max = min = 0;//先让最大和最小的元素下标为0
for (i = 0; i < 10; i++)
{
scanf("%d",&a[i]);
if (a[i] > a[max])
max = i;
if (a[i] < a[min])
min = i;
}
//输入完毕,max和min保留了最大和最小元素的下标
temp = a[max];
a[max] = a[9];
a[9] = temp;
temp = a[min];
a[min] = a[0];
a[0] = temp;
for (i = 0; i < 10; i++)
{
printf("%d ",a[i]);
}
return 0;
}
6.6 priority_queue队列
⭐⭐⭐⭐问题 A: 任务调度
问题描述:读入任务调度序列,输出n个任务适合的一种调度方式。
- 输入
输入包含多组测试数据。
每组第一行输入一个整数n(n<100000),表示有n个任务。
接下来n行,每行第一个表示前序任务,括号中的任务为若干个后序任务,表示只有在前序任务完成的情况下,后序任务才能开始。若后序为NULL则表示无后继任务。
- 输出
输出调度方式,输出如果有多种适合的调度方式,请输出字典序最小的一种。
- 样例输入
4
Task0(Task1,Task2)
Task1(Task3)
Task2(NULL)
Task3(NULL)
- 样例输出
Task0 Task1 Task2 Task3
这道题真是把之前的stl用了个遍,绝绝子
#define _CRT_SECURE_NO_WARNINGS 1
#include <cstdio>
#include <iostream>
#include <unordered_map>
#include <queue>
#include <string>
using namespace std;
struct Task
{
string name;//名字
int level;//顺序
friend bool operator <(const Task& t1, const Task& t2)
{
if (t1.level != t2.level)
return t1.level > t2.level;
else
return t1.name > t2.name;//按照优先级小的排序如果优先级相同就按照字典序小的排序
}
};
//临时字符串str,队列task和无序映射list
void dispose(string str, priority_queue<Task>& task, unordered_map<string, int>& list)
{
string first;
int pos;
int firstlevel;
pos = str.find('(');
first = str.substr(0, pos);//first是前序任务
str.erase(0, pos + 1);
if (list.count(first) == 0)//如果List里面没有这个任务的映射
{
//新建task,并且task的优先级为0
Task newtask;
newtask.name = first;
newtask.level = 0;
//将这个新建的task推入task队列
task.push(newtask);
//记录firstlevel=0;first的映射为0
firstlevel = list[first] = 0;
}
else
{
//如果有这个映射,说明task队列中已经有了这个任务,直接记录first的映射
firstlevel = list[first];
}
while (str.empty() == false)//当str字符串不为空时
{
string last;
pos = str.find(',');
if (pos == string::npos)//如果没有找到,
{
pos = str.find(')');
last = str.substr(0, pos);//直接找括号里唯一的后序任务
str.clear();
}
else
{
last = str.substr(0, pos);//否则记录第一个后续任务
str.erase(0, pos + 1);
}
if (last != "NULL")
{
//还有任务的时候
Task newtask;
newtask.name = last;
//后续任务是前序任务的Level+1
newtask.level = firstlevel + 1;
list[last] = newtask.level;
task.push(newtask);
}
}
}
int main()
{
int n;
while (~scanf("%d", &n))
{
priority_queue<Task> task;//队列task
unordered_map<string, int> list;//task name 到优先级Level的映射
string temp;//临时字符串temp;
//下面输入字符串并排序
for (int i = 0; i < n; i++)
{
cin >> temp;
dispose(temp, task, list);
}
//当队列不为空时,不断输出队首任务
while (task.empty() == false)
{
cout << task.top().name;
task.pop();
if (!task.empty())
{
cout << " ";
}
//每两个任务之间输出空格
}
list.clear();
}
return 0;
}
6.7 stack栈
栈的函数和优先队列基本一致,用途:可以用栈来模拟递归算法(用的也比较少)
⭐⭐⭐⭐问题 A: 简单计算器
问题描述:读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
- 输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
- 输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
- 样例输入
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0
- 样例输出
12178.21
中缀表达式转换为后缀表达式,然后处理数字栈和符号栈
#define _CRT_SECURE_NO_WARNINGS 1
#include <cstdio>
#include <iostream>
#include <string>
#include <unordered_map>
#include <stack>
#include <sstream>
using namespace std;
//将字符变成数字
int str_to_int(const string& string_temp)
{
int temp;
stringstream stream(string_temp);
stream >> temp;
return temp;
}
void compute(stack<double>& number, stack<string>& sign)
{
double b = number.top();
number.pop();
double a = number.top();
number.pop();
string op = sign.top();
sign.pop();
if (op == "+")
{
number.push(a + b);
}
else if (op == "-")
{
number.push(a - b);
}
else if (op == "*")
{
number.push(a * b);
}
else
{
number.push(a / b);
}
}
double dispose(unordered_map<string, int> isp, unordered_map<string, int> osp, string str)
{
stack<double> number;
stack<string> sign;
int flag = 0;
while (str.empty() == false)//当str不为空时
{
string temp;//临时变量temp
int pos = str.find(" ");
//获得第一个数字
if (pos != string::npos)
{
temp += str.substr(0, pos);
str.erase(0, pos + 1);
}
//获得最后一个数字
else
{
temp = str;
str.clear();
}
if (flag == 0)//入栈数字
{
number.push(str_to_int(temp));//将数字入number栈
flag = 1;
}
else//入栈符号
{
if (sign.empty() == false)//sign字符串不为空时
{
if (isp[sign.top()] >= osp[temp])//先乘除后加减
{
while (sign.empty() == false)//sign字符串不为空时
{
if (isp[sign.top()] < osp[temp])
break;
compute(number, sign);
}
}
}
sign.push(temp);//符号入sign栈
flag = 0;
}
}
while (sign.empty() == false)
{
compute(number, sign);
}
return number.top();
}
int main()
{
char a[210];//每行不超过200字符
string temp;
while (gets_s(a))
{
//将表达式存到string中
for (int i = 0; i < 200; i++)
{
if (a[i] != '\0')
{
temp += a[i];
}
else
{
break;
}
}
if (temp != "0")
{
unordered_map<string, int> isp, osp;//定义映射isp和osp
isp["+"] = 1;
isp["-"] = 1;
isp["*"] = 2;
isp["/"] = 2;
osp["+"] = 1;
osp["-"] = 1;
osp["*"] = 2;
osp["/"] = 2;
double result = dispose(isp, osp, temp);
printf("%.2f\n", result);
temp.clear();
}
else
{
break;
}
}
return 0;
}
⭐⭐⭐⭐问题 B: Problem E
待解决
6.8 pair常见用法
1、用来代替二元结构体及其构造函数
2、作为map的键值来进行插入
问题 A: 重心在哪里
问题描述:每个人都知道牛顿发现万有引力的故事。自从牛顿发现万有引力后,人们用万有引力理论解决了非常多的问题。不仅如此,我们也知道了每个物体都有自己的重心。
现在,给你三角形三个顶点的坐标,你能计算出三角形的重心吗?
- 输入
题目包含多组测试数据。第一行输入一个正整数n,表示测试数据的个数,当n=0时,输入结束。
接下来n行,每行包含6个数字x1,y1,x2,y2,x3,y3,表示三角形三个顶点的坐标。
- 输出
对于每组输入,输出重心的坐标,结果保留1位小数。
- 样例输入
2
1.0 2.0 3.0 4.0 5.0 2.0
1.0 1.0 4.0 1.0 1.0 5.0
0
- 样例输出
3.0 2.7
2.0 2.3
#define _CRT_SECURE_NO_WARNINGS 1
#include <cstdio>
#include <iostream>
#include <string>
#include <unordered_map>
#include <stack>
#include<map>
#include <sstream>
using namespace std;
int main()
{
pair<double, double> p[4];
int n, i,j;
while (scanf("%d", &n) != EOF)
{
if (n == 0)
break;
for (i = 0; i < n; i++)
{
for (j = 0; j < 3; j++)
scanf("%lf %lf", &p[j].first, &p[j].second);//输入
p[3].first = (p[0].first + p[2].first + p[1].first) * 1.0 / 3;
p[3].second = (p[0].second + p[2].second + p[1].second) * 1.0 / 3;
printf("%.1f %.1f\n", p[3].first, p[3].second);
}
}
return 0;
}
6.9 algorithm
问题AC都是基础题,代码不贴了
问题 B: 全排列
问题描述:给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
我们假设对于小写字母有’a’ < ‘b’ < … < ‘y’ < ‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。
- 输入
输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
- 输出
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:
已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存在p (1 <= p <= k),使得
s1 = t1, s2 = t2, ..., sp - 1 = tp - 1, sp < tp成立。
注意每组样例输出结束后接一个空行。
- 样例输入
xyz
- 样例输出
xyz
xzy
yxz
yzx
zxy
zyx
这题注意使用next_permutation就可以啦
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
char a[1100];
int len;
while (scanf("%s", a)!=EOF)
{
len = strlen(a);
do {
printf("%s\n",a);
} while (next_permutation(a, a+len));
printf("\n");
}
return 0;
}
第六章终于结束了,真是艰难的一章啊~后仰