本文主要是介绍HDU1153——Magic Bitstrings,HDU1171——Big Event in HDU,HDU1261——字串数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
HDU1153——Magic Bitstrings
题目描述
问题 - 1153 (hdu.edu.cn)

运行代码
#include <iostream>
#include <vector>int main() {long long p;while (std::cin >> p) {if (p == 0) break;if (p == 2) {std::cout << "Impossible" << std::endl;} else {std::vector<int> a(p, 1);for (long long i = 1; i < p; i++) {a[i * i % p] = 0;}for (int i = 1; i < p; i++) {std::cout << a[i];}std::cout << std::endl;}}return 0;
}
代码思路
- 从标准输入不断读取整数
p,直到读取到0为止。 - 对于每个非零的输入
p,进行以下处理:- 如果
p等于2,直接输出"Impossible",因为在这种情况下无法按照后续逻辑生成所需的序列。 - 否则,创建一个长度为
p的std::vector<int>容器a,并初始化为所有元素都是1。 - 接着通过一个循环,对于从
1到p - 1的每个整数i,计算i * i % p,并将向量a中对应位置的元素设置为0。 - 最后遍历向量
a,输出其中从索引1到p - 1的每个元素,得到最终的序列。
- 如果
-
输入处理循环:
while (std::cin >> p)这个循环会不断读取标准输入的整数赋值给p。只要输入不为0,循环就会继续执行,这样可以处理多个输入值。 -
特殊情况判断:当
p等于2时,根据问题的要求输出"Impossible"。这是因为当p = 2时,无法按照后续的逻辑生成满足条件的序列。 -
向量初始化与修改:
std::vector<int> a(p, 1)创建了一个长度为p的向量a,并将所有元素初始化为1。这意味着初始状态下,向量中的每个位置都被设置为1。for (long long i = 1; i < p; i++) { a[i * i % p] = 0; }这个循环遍历从1到p - 1的整数i。对于每个i,计算i * i % p,这实际上是找到i的平方对p取模的结果。然后将向量a中对应这个位置的元素设置为0。这样就标记了所有平方数模p的位置。 -
输出结果:
for (int i = 1; i < p; i++) { std::cout << a[i]; }遍历向量a,从索引1开始输出每个元素,从而得到最终的序列。如果a的索引从0开始,那么当p = 2时,可能会导致输出错误的结果,所以从索引1开始输出。输出的序列中,对应平方数模p的位置为0,其余位置为1。
HDU1171——Big Event in HDU
题目描述
Problem - 1171 (hdu.edu.cn)

运行代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {int n;while (cin >> n && n > 0) {vector<int> values;double sum = 0.0;for (int i = 0; i < n; ++i) {int x, y;cin >> x >> y;sum += x * y;for (int j = 0; j < y; ++j) {values.push_back(x);}}double target = sum / 2.0;sort(values.begin(), values.end(),greater<int>());double a = 0.0;for (int v : values) {if (a + v > target) continue;a += v;}double b = sum - a;if (b > a) swap(a, b);cout << (long long)a << " " << (long long)b << endl;}return 0;
}
代码思路
一、整体思路
- 不断从输入读取设施的数量
n,只要n大于0就继续处理一个测试用例。 - 对于每个测试用例,读取
n组设施的价值x和数量y,并计算所有设施的总价值sum,同时将每个设施的值按照数量加入到一个vector容器values中。 - 确定总价值的一半作为分割目标
target。 - 对
values中的设施价值进行降序排序。 - 从大到小遍历排序后的设施价值,将设施分配给两个学院,使得两个学院的价值尽量接近总价值的一半,记录下最终两个学院的价值
a和b,并保证a不小于b。 - 输出
a和b。
二、原理分析
-
输入处理循环:
while (cin >> n && n > 0)这个循环会持续读取输入的n,只要n是正整数,就表示有一个新的测试用例需要处理。如果n小于或等于0,则退出循环,结束程序。 -
读取设施信息和计算总价值:
- 对于每个测试用例,循环
n次读取每组设施的价值x和数量y。 sum += x * y这句代码计算所有设施的总价值,通过将每个设施的价值乘以数量并累加到sum中。- 同时,通过嵌套的循环
for (int j = 0; j < y; ++j)将每个设施的值按照数量加入到values容器中,这样values中存储了所有设施的具体价值。
- 对于每个测试用例,循环
-
确定分割目标:
double target = sum / 2.0计算总价值的一半,这是分割设施的目标值。目的是将设施分配给两个学院,使得每个学院的价值尽量接近总价值的一半。 -
排序设施价值:
sort(values.begin(), values.end(), greater<int>());使用标准库的排序函数对values中的设施价值进行降序排序。这样做的目的是在分配设施时,从价值较大的设施开始考虑,以便更快地接近分割目标。 -
分配设施并计算两个学院的价值:
double a = 0.0;和double b = sum - a;分别表示两个学院的价值,初始时a为0,b为总价值。- 遍历排序后的设施价值,对于每个设施价值
v,如果将其加入a后不超过分割目标target,则将其加入a,即a += v;。如果超过了目标,则不加入。 - 最后,
b = sum - a;计算出另一个学院的价值。如果b大于a,则交换a和b,以保证a不小于b。
-
输出结果:
cout << (long long)a << " " << (long long)b << endl;将a和b转换为长整型后输出,代表两个学院最终的价值。
HDU1261——字串数
题目描述
问题 - 1261 (hdu.edu.cn)

运行代码
#include <iostream>
#include <vector>
#include<algorithm>
#include <numeric>
using namespace std;// 高精度乘法
vector<int> multiply(const vector<int>& v, int factor) {vector<int> result;int carry = 0;for (int i = 0; i < v.size(); ++i) {int temp = v[i] * factor + carry;result.push_back(temp % 10);carry = temp / 10;}while (carry > 0) {result.push_back(carry % 10);carry /= 10;}return result;
}// 高精度除法
vector<int> divide(const vector<int>& v, int divisor) {vector<int> result;int remainder = 0;for (int i = v.size() - 1; i >= 0; --i) {int temp = remainder * 10 + v[i];result.push_back(temp / divisor);remainder = temp % divisor;}reverse(result.begin(), result.end());while (result.size() > 1 && result.back() == 0) result.pop_back();return result;
}void solve(int n, const vector<int>& a) {vector<int> factorial{ 1 };for (int i = 2; i <= accumulate(a.begin(), a.end(), 0); ++i) {factorial = multiply(factorial, i);}for (int i = 0; i < n; ++i) {for (int j = 2; j <= a[i]; ++j) {factorial = divide(factorial, j);}}for (int i = factorial.size() - 1; i >= 0; --i) {cout << factorial[i];}cout << endl;
}int main() {int n;while (cin >> n && n != 0) {vector<int> a(n);int sum = 0;for (int i = 0; i < n; ++i) {cin >> a[i];sum += a[i];}solve(n, a);}return 0;
}
代码思路
一、整体思路
- 从标准输入不断读取整数
n,只要n不为0,就处理一个新的测试用例。 - 对于每个测试用例,读取
n个整数存入vector<int> a,并计算这些整数的总和sum。 - 通过一系列高精度计算函数,计算出给定数字组合下的结果并输出。
二、具体函数分析
-
高精度乘法函数
multiply:- 接收一个整数向量
v和一个整数factor,模拟高精度乘法。 - 遍历输入向量的每个元素,将其与
factor相乘并加上进位carry,计算出当前位的结果和新的进位。 - 当进位不为
0时,继续将进位加入结果向量中。 - 最终返回表示乘积的向量。
- 接收一个整数向量
-
高精度除法函数
divide:- 接收一个整数向量
v和一个整数divisor,模拟高精度除法。 - 从高位到低位遍历输入向量,将当前位与上一位的余数组合,进行除法运算,得到商和新的余数。
- 将商存入结果向量中,最后反转结果向量并去除前导零。
- 返回表示商的向量。
- 接收一个整数向量
-
求解函数
solve:- 接收整数
n和整数向量a,用于计算特定问题的结果。 - 首先初始化一个表示
1的向量factorial。 - 通过循环从
2到输入数字总和(通过std::accumulate(a.begin(), a.end(), 0)计算得到),每次将factorial与当前数字相乘,模拟求阶乘的过程。 - 然后对于每个输入的数字
a[i],从2到a[i]循环,将factorial除以当前数字,去除重复的组合。 - 最后,从高位到低位输出
factorial,即最终结果。
- 接收整数
-
主函数
main:- 循环读取输入的
n,如果n为0则结束程序。 - 对于每个测试用例,创建一个长度为
n的向量a,读取n个整数存入a,并计算这些整数的总和sum。 - 调用
solve函数处理当前测试用例并输出结果。
- 循环读取输入的
这篇关于HDU1153——Magic Bitstrings,HDU1171——Big Event in HDU,HDU1261——字串数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!