目录
HDU1071——The area
题目描述
运行代码
代码思路
HDU1072——Nightmare
题目描述
运行代码
代码思路
HDU1073——Online Judge
题目描述
运行代码
代码思路
HDU1071——The area
题目描述
Problem - 1071
运行代码
#include <iostream>
#include <cmath>
#include<stdio.h>
#include<algorithm>
// 计算抛物线和直线围成的面积
double calculateArea(double x1, double y1, double x2, double y2, double x3, double y3) {
// 抛物线顶点为 (x1, y1),设抛物线方程为 y = a(x - x1)^2 + y1
// 通过 (x2, y2) 和 (x3, y3) 两点求出直线方程 y = kx + b
double a, k, b;
// 计算抛物线系数 a
if (x2 != x1 && x3 != x1) {
a = (y2 - y1) / pow((x2 - x1), 2);
}
else {
std::cerr << "Invalid input: x2 or x3 cannot be equal to x1." << std::endl;
return -1;
}
// 计算直线斜率 k 和截距 b
k = (y3 - y2) / (x3 - x2);
b = y2 - k * x2;
// 积分计算面积
double area = 0;
double left = std::min(x2, x3);
double right = std::max(x2, x3);
for (double x = left; x <= right; x += 0.0001) {
double yParabola = a * pow((x - x1), 2) + y1;
double yLine = k * x + b;
area += std::abs(yParabola - yLine) * 0.0001;
}
return area;
}
int main() {
int T;
std::cin >> T;
while (T--) {
double x1, y1, x2, y2, x3, y3;
std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
double area = calculateArea(x1, y1, x2, y2, x3, y3);
std::printf("%.2f\n", area);
}
return 0;
}
代码思路
calculateArea
函数:
- 首先,根据给定的顶点
(x1, y1)
以及另外两个点(x2, y2)
和(x3, y3)
来计算抛物线和直线的参数。- 对于抛物线,通过
(x1, y1)
和(x2, y2)
计算出系数a
,前提是x2
和x1
不相等。 - 对于直线,通过
(x2, y2)
和(x3, y3)
计算出斜率k
和截距b
。
- 对于抛物线,通过
- 然后,通过积分的思想来近似计算抛物线和直线所围成的面积。
- 确定积分的区间,即
x
的范围为x2
和x3
中的较小值到较大值。 - 对于区间内的每个小间隔
0.0001
,计算对应的抛物线纵坐标yParabola
和直线纵坐标yLine
的差值的绝对值,乘以间隔宽度0.0001
,并累加到面积area
中。
- 确定积分的区间,即
main
函数:
- 读取测试用例的数量
T
。 - 在每个测试用例中,读取三个交点的坐标。
- 调用
calculateArea
函数计算面积。 - 使用
printf
以保留两位小数的格式输出计算得到的面积。
HDU1072——Nightmare
题目描述
Problem - 1072
运行代码
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
char mapp[9][9];
int vis[9][9];
int dis[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};
int n, m, f_x, f_y;
// 坐标结构体,存储总时间,和炸弹倒计时
struct Coordinate {
int x, y, to_time, now_time;
};
// 判断越界等状况
bool judge(int x, int y) {
if (x < 0 || y < 0 || x >= n || y >= m || mapp[x][y] == '0') return false;
return true;
}
int bfs(int x, int y) {
int i;
queue<Coordinate> q;
Coordinate a, b;
memset(vis, 0, sizeof(vis));
// 对队列与起点的初始化
vis[x][y] = 6;
a = {x, y, 0, 6};
q.push(a);
while (!q.empty()) {
a = q.front();
q.pop();
if (a.x == f_x && a.y == f_y) return a.to_time;
for (i = 0; i < 4; ++i) {
b.x = a.x + dis[i][0];
b.y = a.y + dis[i][1];
if (judge(b.x, b.y)) {
// 如果踩到重置时间
if (mapp[b.x][b.y] == '4') {
if (a.now_time == 1) continue;
b = {b.x, b.y, a.to_time + 1, 6};
} else {
b = {b.x, b.y, a.to_time + 1, a.now_time - 1};
}
// 判断后到达的此点剩余时间是否 大于 之前到达这个点剩余时间
if (b.now_time <= vis[b.x][b.y]) continue;
vis[b.x][b.y] = b.now_time;
q.push(b);
}
}
}
return -1;
}
int main() {
int total_case, i, j;
int s_x, s_y;
cin >> total_case;
while (total_case--) {
cin >> n >> m;
// 输入时记录起点与终点坐标
for (i = 0; i < n; ++i) {
for (j = 0; j < m; ++j) {
cin >> mapp[i][j];
if (mapp[i][j] == '2') {
s_x = i;
s_y = j;
}
if (mapp[i][j] == '3') {
f_x = i;
f_y = j;
}
}
}
cout << bfs(s_x, s_y) << endl;
}
return 0;
}
代码思路
整体思路:
这段代码主要实现了一个使用广度优先搜索(BFS)算法来解决一个在特定地图上的时间相关的路径搜索问题。
数据结构:
mapp[9][9]
用于存储地图信息,不同的字符表示不同的地图元素。vis[9][9]
用于记录每个位置被访问时的剩余时间。dis[4][2]
表示四个方向的偏移量,用于在搜索时向四个方向移动。
结构体 Coordinate
:定义了一个结构体来存储坐标 x
和 y
,以及到达该坐标的总时间 to_time
和当前剩余时间 now_time
。
函数 judge
:用于判断给定的坐标是否合法,即是否越界或遇到不可通过的区域(值为 '0'
)。
函数 bfs
:这是 BFS 的核心函数。
- 初始化队列
q
,将起点加入队列,并设置起点的访问时间vis
为 6 。 - 当队列不为空时,取出队首元素。
- 如果队首元素的坐标就是终点坐标,返回总时间。
- 对于四个方向,计算新的坐标。
- 如果新坐标合法:如果踩到重置时间(值为
'4'
)且当前剩余时间不为 1,则更新新坐标的总时间和剩余时间为 6,并在新的剩余时间大于之前记录的剩余时间时,将新坐标加入队列并更新访问时间。如果不是踩到重置时间,则更新新坐标的总时间和剩余时间,并在新的剩余时间大于之前记录的剩余时间时,将新坐标加入队列并更新访问时间。
主函数 main
:
- 读入测试用例的数量
total_case
。 - 在每个测试用例中,读入地图的大小
n
和m
。 - 读入地图信息,同时记录起点和终点的坐标。
- 调用
bfs
函数进行搜索,并输出结果。
解题思路:
通过 BFS 逐层扩展搜索,根据地图中的元素和时间规则,找到从起点到终点的最短时间路径。在搜索过程中,利用 vis
数组记录每个位置的最优时间,避免重复访问和无效搜索,最终找到满足条件的最短时间。
HDU1073——Online Judge
题目描述
Problem - 1073
运行代码
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 去除字符串中的空格、制表符和换行符
void eraseSpecialChars(string& s) {
s.erase(remove(s.begin(), s.end(), ' '), s.end());
s.erase(remove(s.begin(), s.end(), '\t'), s.end());
s.erase(remove(s.begin(), s.end(), '\n'), s.end());
}
int main() {
int t;
cin >> t;
while (t--) {
vector<string> correctLines, userLines;
string line;
// 读取正确输出
while (getline(cin, line)) {
if (line == "START") {
continue;
}
else if (line == "END") {
break;
}
correctLines.push_back(line);
}
// 读取用户输出
while (getline(cin, line)) {
if (line == "START") {
continue;
}
else if (line == "END") {
break;
}
userLines.push_back(line);
}
bool isAccepted = true; // 假设是已接受
// 比较每行是否相同
for (size_t i = 0; i < max(correctLines.size(), userLines.size()); ++i) {
if (i >= correctLines.size() || i >= userLines.size() || correctLines[i] != userLines[i]) {
isAccepted = false;
break;
}
}
if (isAccepted) {
cout << "Accepted" << endl;
}
else {
string correctStr, userStr;
for (const auto& line : correctLines) {
correctStr += line + '\n';
}
for (const auto& line : userLines) {
userStr += line + '\n';
}
eraseSpecialChars(correctStr);
eraseSpecialChars(userStr);
if (correctStr != userStr) {
cout << "Wrong Answer" << endl;
}
else {
cout << "Presentation Error" << endl;
}
}
}
return 0;
}
代码思路
-
先,定义了一个函数
eraseSpecialChars
用于去除字符串中的空格、制表符和换行符。 -
在
main
函数中,首先读取测试用例的数量t
。 -
对于每个测试用例,使用两个
vector
分别存储正确输出的行correctLines
和用户输出的行userLines
。 -
通过循环使用
getline
函数读取输入,将有效的行分别添加到对应的vector
中。 -
初始化一个标志
isAccepted
为true
,表示假设结果是已接受的。 -
然后遍历两个
vector
比较每行的内容,如果有不同则将isAccepted
置为false
并退出循环。 -
如果
isAccepted
仍然为true
,说明结果是已接受的,输出 "Accepted" 。 -
如果
isAccepted
为false
,则将两个vector
中的内容连接成字符串correctStr
和userStr
,并调用eraseSpecialChars
函数去除特殊字符。 -
比较去除特殊字符后的两个字符串,如果不同输出 "Wrong Answer" ,否则输出 "Presentation Error" 。