HDU1071——The area,HDU1072——Nightmare,HDU1073——Online Judge

目录

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 函数

  1. 首先,根据给定的顶点 (x1, y1) 以及另外两个点 (x2, y2) 和 (x3, y3) 来计算抛物线和直线的参数。
    • 对于抛物线,通过 (x1, y1) 和 (x2, y2) 计算出系数 a,前提是 x2 和 x1 不相等。
    • 对于直线,通过 (x2, y2) 和 (x3, y3) 计算出斜率 k 和截距 b 。
  2. 然后,通过积分的思想来近似计算抛物线和直线所围成的面积。
    • 确定积分的区间,即 x 的范围为 x2 和 x3 中的较小值到较大值。
    • 对于区间内的每个小间隔 0.0001,计算对应的抛物线纵坐标 yParabola 和直线纵坐标 yLine 的差值的绝对值,乘以间隔宽度 0.0001 ,并累加到面积 area 中。

main 函数

  1. 读取测试用例的数量 T 。
  2. 在每个测试用例中,读取三个交点的坐标。
  3. 调用 calculateArea 函数计算面积。
  4. 使用 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 的核心函数。

  1. 初始化队列 q,将起点加入队列,并设置起点的访问时间 vis 为 6 。
  2. 当队列不为空时,取出队首元素。
  3. 如果队首元素的坐标就是终点坐标,返回总时间。
  4. 对于四个方向,计算新的坐标。
  5. 如果新坐标合法:如果踩到重置时间(值为 '4')且当前剩余时间不为 1,则更新新坐标的总时间和剩余时间为 6,并在新的剩余时间大于之前记录的剩余时间时,将新坐标加入队列并更新访问时间。如果不是踩到重置时间,则更新新坐标的总时间和剩余时间,并在新的剩余时间大于之前记录的剩余时间时,将新坐标加入队列并更新访问时间。

主函数 main

  1. 读入测试用例的数量 total_case 。
  2. 在每个测试用例中,读入地图的大小 n 和 m 。
  3. 读入地图信息,同时记录起点和终点的坐标。
  4. 调用 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;
}

代码思路

  1. 先,定义了一个函数 eraseSpecialChars 用于去除字符串中的空格、制表符和换行符。

  2. 在 main 函数中,首先读取测试用例的数量 t 。

  3. 对于每个测试用例,使用两个 vector 分别存储正确输出的行 correctLines 和用户输出的行 userLines 。

  4. 通过循环使用 getline 函数读取输入,将有效的行分别添加到对应的 vector 中。

  5. 初始化一个标志 isAccepted 为 true ,表示假设结果是已接受的。

  6. 然后遍历两个 vector 比较每行的内容,如果有不同则将 isAccepted 置为 false 并退出循环。

  7. 如果 isAccepted 仍然为 true ,说明结果是已接受的,输出 "Accepted" 。

  8. 如果 isAccepted 为 false ,则将两个 vector 中的内容连接成字符串 correctStr 和 userStr ,并调用 eraseSpecialChars 函数去除特殊字符。

  9. 比较去除特殊字符后的两个字符串,如果不同输出 "Wrong Answer" ,否则输出 "Presentation Error" 。

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱姌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值