目录
HDU1075——What Are You Talking About
代码思路
HDU1074——Doing Homework
题目描述
运行代码
#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;
}
代码思路
-
首先定义了一些常量和结构体。
Point
结构体用于存储每个作业的信息,包括名称、截止日期和完成所需时间。father
结构体用于存储动态规划过程中的中间状态信息,如父节点状态、选择的作业、扣掉的分数和累计花费时间。 -
在
main
函数中,首先读取测试用例的数量t
。 -
对于每个测试用例:
- 读取作业的数量
n
,并输入每个作业的详细信息。 - 计算可能的状态总数
end
,通过1 << n
得到。 - 然后通过两层循环进行动态规划:外层循环枚举所有可能的状态
i
。内层循环从后往前遍历每个作业j
。如果当前作业在状态i
中,计算完成当前作业可能导致的扣分数ans
。如果扣分数加上前一状态的扣分数小于当前状态的扣分数,就更新当前状态的信息,包括扣分数、父节点、选择的作业和累计花费时间。 - 输出最终状态(完成所有作业)的扣分数。
- 使用一个栈
q
来存储选择作业的顺序。通过从最终状态回溯,将选择的作业序号入栈。 - 最后从栈中依次取出作业序号,并输出对应的作业名称。
- 读取作业的数量
HDU1075——What Are You Talking About
题目描述
![](https://i-blog.csdnimg.cn/direct/033b2c81c7f841d38cd0292ef3c54eb2.png)
运行代码
#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;
}
代码思路
-
数据结构定义
- 定义了一个结构体
node
来表示字典树的节点。每个节点包含一个vector<node*>
用于存储子节点指针,一个字符串s
用于记录对应的单词(在插入时使用),一个整数num
用于标识节点代表的字符,以及一些初始化操作。
- 定义了一个结构体
-
函数
find_and_insert
- 这个函数用于在字典树中查找或插入字符串。
- 如果当前位置
x
等于字符串的长度len
,根据操作标志ope
决定是否记录单词。 - 如果还未到达字符串末尾,遍历当前节点的子节点,如果找到字符对应的子节点,就递归地在该子节点上继续操作。
- 如果没有找到对应的子节点,并且是插入操作(
ope
为 1),则创建新的子节点并继续递归插入。
-
main
函数- 首先创建字典树的根节点。
- 通过一个循环读取单词和对应的字符串,并调用
find_and_insert
函数将单词插入字典树。 - 接下来读取输入的字符串。
- 对于输入的字符串,逐个字符处理。如果是小写字母,将其对应的数字存入
num
数组,并累计到s2
中。如果遇到非小写字母,通过find_and_insert
函数查找当前累计的字母组成的字符串是否在字典树中有对应单词,如果没有则直接将累计的字符串添加到结果s
中,否则添加查找到的单词。最后将非小写字母也添加到结果中。
总的来说,这段代码的主要目的是构建一个字典树来存储单词,并能够对输入的字符串进行处理,将其中能在字典树中找到对应单词的部分替换为单词,其余部分保持不变。
HDU1076——An Easy Task
题目描述
运行代码
#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;
}
代码思路
- 首先读取测试用例的数量 T 。
- 对于每个测试用例,读取起始年份 Y 和要找的第 N 个闰年。
- 从起始年份 Y 开始,依次判断每个年份是否为闰年,如果是闰年就计数器加 1 ,直到计数器达到 N ,输出该年份。
- 判断闰年的条件是 ( Y % 4 == 0 且 Y % 100!= 0 ) 或者 Y % 400 == 0 。