HDU1074——Doing Homework,HDU1075——What Are You Talking About,HDU1076——An Easy Task

38 篇文章 0 订阅

目录

HDU1074——Doing Homework

题目描述

运行代码

代码思路

HDU1075——What Are You Talking About

题目描述

​编辑​编辑运行代码

代码思路

HDU1076——An Easy Task

题目描述

​编辑 运行代码

代码思路​​​​​​​

HDU1074——Doing Homework

题目描述

Problem - 1074

运行代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>

using namespace std;

const int maxn = 101;
const int INF = 0x3f3f3f3f;

struct Point {
    char str[maxn];
    int dead;
    int cost;
} point[maxn];

struct father {
    int dad, book, score, time;
} dp[1 << 15];

int main() {
    int t;
    cin >> t;

    while (t--) {
        int n;
        cin >> n;

        for (int i = 0; i < n; i++) {
            cin >> point[i].str >> point[i].dead >> point[i].cost;
        }

        int end = 1 << n;

        for (int i = 1; i < end; i++) {
            dp[i].score = INF;

            for (int j = n - 1; j >= 0; j--) {
                int temp = 1 << j;

                if (temp & i) {
                    int tem = i - temp;
                    int ans = dp[tem].time + point[j].cost - point[j].dead;

                    if (ans < 0) {
                        ans = 0;
                    }

                    if (ans + dp[tem].score < dp[i].score) {
                        dp[i].score = ans + dp[tem].score;
                        dp[i].dad = tem;
                        dp[i].book = j;
                        dp[i].time = dp[tem].time + point[j].cost;
                    }
                }
            }
        }

        cout << dp[end - 1].score << endl;

        stack<int> q;
        int tt = end - 1;

        while (dp[tt].time) {
            q.push(dp[tt].book);
            tt = dp[tt].dad;
        }

        while (!q.empty()) {
            int k = q.top();
            cout << point[k].str << endl;
            q.pop();
        }
    }

    return 0;
}

代码思路

  1. 首先定义了一些常量和结构体。Point结构体用于存储每个作业的信息,包括名称、截止日期和完成所需时间。father结构体用于存储动态规划过程中的中间状态信息,如父节点状态、选择的作业、扣掉的分数和累计花费时间。

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

  3. 对于每个测试用例:

    • 读取作业的数量n,并输入每个作业的详细信息。
    • 计算可能的状态总数end,通过1 << n得到。
    • 然后通过两层循环进行动态规划:外层循环枚举所有可能的状态i。内层循环从后往前遍历每个作业j。如果当前作业在状态i中,计算完成当前作业可能导致的扣分数ans。如果扣分数加上前一状态的扣分数小于当前状态的扣分数,就更新当前状态的信息,包括扣分数、父节点、选择的作业和累计花费时间。
    • 输出最终状态(完成所有作业)的扣分数。
    • 使用一个栈q来存储选择作业的顺序。通过从最终状态回溯,将选择的作业序号入栈。
    • 最后从栈中依次取出作业序号,并输出对应的作业名称。

HDU1075——What Are You Talking About

题目描述

运行代码

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<string>
#include<vector>
using namespace std;
string s1, s2, s;
int num[15];
struct node
{
    vector<node*>next;
    string s;
    int num;
    node()
    {
        num = 0;
        s = "";
        next.clear();
    }
}*tree, * add;
string find_and_insert(node* now, int x, int len, int ope)
{
    if (x == len)
    {
        if (ope)
            now->s = s1;//记录该串所对应的单词
        return now->s;
    }
    for (int i = 0; i < now->next.size(); i++)
    {
        if (now->next[i]->num != num[x])
            continue;
        return find_and_insert(now->next[i], x + 1, len, ope);
    }
    if (ope)
    {
        add = new node;
        add->num = num[x];
        now->next.push_back(add);
        return find_and_insert(add, x + 1, len, ope);
    }
    else
        return "";
}
int main()
{
    tree = new node;
    add = new node;
    while (cin >> s1)
    {
        if (s1 == "START")
            continue;
        if (s1 == "END")
            break;
        cin >> s2;
        for (int i = 0; i < s2.size(); i++)
            num[i] = s2[i] - 'a';
        find_and_insert(tree, 0, s2.size(), 1);//将该单词插入字典树
    }
    cin >> s1; getchar();//“START”
    s1 = s2 = "";
    char str[3030];
    memset(str, 0, sizeof str);
    while (gets_s(str))//可能在每串字符前面也有空格,所以只能用gets()或getchar()
    {
        for (int i = 0; i < strlen(str); i++)
            s1 += str[i];
        memset(str, 0, sizeof str);
        s = "";
        if (s1 == "END")
            break;
        s1 += '\n';
        int k = 0;
        for (int i = 0; i < s1.size(); i++)
        {
            if (s1[i] >= 'a' && s1[i] <= 'z')
            {
                num[k++] = s1[i] - 'a';
                s2 += s1[i];
            }
            else
            {
                string ss = find_and_insert(tree, 0, k, 0);
                if (ss == "" && s2.size() != 0)//表示这串字母没有对应的单词
                    s += s2;
                else
                    s += ss;
                k = 0;
                s += s1[i];
                s2 = "";
            }
        }
        s1 = "";
        cout << s;
    }
    return 0;
}

代码思路

  1. 数据结构定义

    • 定义了一个结构体 node 来表示字典树的节点。每个节点包含一个 vector<node*> 用于存储子节点指针,一个字符串 s 用于记录对应的单词(在插入时使用),一个整数 num 用于标识节点代表的字符,以及一些初始化操作。
  2. 函数 find_and_insert

    • 这个函数用于在字典树中查找或插入字符串。
    • 如果当前位置 x 等于字符串的长度 len ,根据操作标志 ope 决定是否记录单词。
    • 如果还未到达字符串末尾,遍历当前节点的子节点,如果找到字符对应的子节点,就递归地在该子节点上继续操作。
    • 如果没有找到对应的子节点,并且是插入操作(ope 为 1),则创建新的子节点并继续递归插入。
  3. main 函数

    • 首先创建字典树的根节点。
    • 通过一个循环读取单词和对应的字符串,并调用 find_and_insert 函数将单词插入字典树。
    • 接下来读取输入的字符串。
    • 对于输入的字符串,逐个字符处理。如果是小写字母,将其对应的数字存入 num 数组,并累计到 s2 中。如果遇到非小写字母,通过 find_and_insert 函数查找当前累计的字母组成的字符串是否在字典树中有对应单词,如果没有则直接将累计的字符串添加到结果 s 中,否则添加查找到的单词。最后将非小写字母也添加到结果中。

总的来说,这段代码的主要目的是构建一个字典树来存储单词,并能够对输入的字符串进行处理,将其中能在字典树中找到对应单词的部分替换为单词,其余部分保持不变。

HDU1076——An Easy Task

题目描述

Problem - 1076

 运行代码

#include<iostream>
bool leap(int n) {
	return  (n % 4 == 0 && n % 100 != 0) || n % 400 == 0;
}
int main() {
	int T;
	scanf_s("%d", &T);
	while (T--) {
		int Y, N;
		scanf_s("%d%d", &Y, &N);
		int c = 0;
		while (c < N) {
			if (leap(Y)) {
				c++;
			}
			if (c < N) {
				Y++;
			}
		}
		printf("%d\n", Y);
	}
	return 0;
}

代码思路

  1. 首先读取测试用例的数量 T 。
  2. 对于每个测试用例,读取起始年份 Y 和要找的第 N 个闰年。
  3. 从起始年份 Y 开始,依次判断每个年份是否为闰年,如果是闰年就计数器加 1 ,直到计数器达到 N ,输出该年份。
  4. 判断闰年的条件是 ( Y % 4 == 0 且 Y % 100!= 0 ) 或者 Y % 400 == 0 。
  • 32
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

筱姌

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

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

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

打赏作者

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

抵扣说明:

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

余额充值