目录
[HDU1014------Uniform Generator](#HDU1014——Uniform Generator)
[HDU1016------Prime Ring Problem](#HDU1016——Prime Ring Problem)
HDU1014------Uniform Generator
题目描述
运行代码
cpp
#include <iostream>
using namespace std;
bool Choice(int step, int mod) {
bool visited[100005];
for (int i = 0; i < mod; i++) {
visited[i] = false;
}
int cur = 0;
for (int i = 0; i < mod; i++) {
visited[cur] = true;
cur = (cur + step) % mod;
}
for (int i = 0; i < mod; i++) {
if (!visited[i]) {
return false;
}
}
return true;
}
int main() {
int step, mod;
while (cin >> step >> mod) {
cout.width(10);
cout << right << step;
cout.width(10);
cout << right << mod;
if (Choice(step, mod)) {
cout << " Good Choice" << endl;
}
else {
cout << " Bad Choice" << endl;
}
cout << endl;
}
return 0;
}
代码思路
-
定义
Choice
函数:- 接收两个整数参数
step
和mod
。 - 创建一个布尔型数组
visited
,用于标记0到mod-1
之间的每个数是否已被访问。 - 初始化
visited
数组,将所有元素设为false
。 - 从
cur = 0
开始,按step
步长进行移动,使用模运算保证cur
始终在0到mod-1
范围内。 - 每次移动都将
cur
位置标记为已访问,然后更新cur
的值。 - 最后,遍历
visited
数组,检查是否有未被访问的位置。 - 如果所有位置都被访问过,则返回
true
,表示这是个好的选择;否则返回false
。
- 接收两个整数参数
-
main
函数:- 读取标准输入中的
step
和mod
,直到没有更多输入为止。 - 使用
cout
的宽度设置和右对齐功能来格式化输出,使得输出更加整齐。 - 调用
Choice
函数,根据返回值判断并输出是"Good Choice"还是"Bad Choice"。
- 读取标准输入中的
HDU1015------Safecracker
题目描述
运行代码
cpp
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
int fun(int a, int b, int c, int d, int e)
{
if (a == b || a == c || a == d || a == e)return 0;
if (b == c || b == d || b == e)return 0;
if (c == d || c == e)return 0;
if (d == e)return 0;
return 1;
}
int cmp(char a, char b)
{
return a > b;
}
int main()
{
int n, t, len;
char str[15];
int v, w, x, y, z, f;
int vv, ww, xx, yy, zz;
while (scanf("%d %s", &n, str) != -1)
{
if (n == 0 && strcmp(str, "END") == 0)break;
t = 0;
f = 0;
len = strlen(str);
sort(str, str + len, cmp);
for (v = 0; str[v]; v++)
{
for (w = 0; str[w]; w++)
{
for (x = 0; str[x]; x++)
{
for (y = 0; str[y]; y++)
{
for (z = 0; str[z]; z++)
{
if (fun(v, w, x, y, z))
{
vv = str[v] - 'A' + 1;
ww = str[w] - 'A' + 1;
xx = str[x] - 'A' + 1;
yy = str[y] - 'A' + 1;
zz = str[z] - 'A' + 1;
if (vv - ww * ww + xx * xx * xx
- yy * yy * yy * yy + zz * zz * zz * zz * zz == n)
{
f = 1;
printf("%c%c%c%c%c\n", str[v], str[w], str[x], str[y], str[z]);
break;
}
}
}if (f)break;
}if (f)break;
}if (f)break;
}if (f)break;
}
if (!f)printf("no solution\n");
}
return 0;
}
代码思路
-
函数定义 :
fun()
函数用于检查五个字母是否互不相同。cmp()
函数用于降序排序字母。 -
主函数逻辑:
- 循环读取输入直到遇到终止条件(
n == 0
和str
为"END")。 - 将输入的字符串
str
降序排序。 - 使用五层嵌套循环遍历所有可能的五字母组合。
- 使用
fun()
函数检查字母是否互不相同。 - 如果满足条件,计算等式左侧的值,并与给定的整数
n
比较。 - 如果等式成立,打印出这组字母并退出所有循环。
- 如果遍历结束后仍未找到满足条件的组合,输出"no solution"。
- 循环读取输入直到遇到终止条件(
优化建议
-
减少不必要的比较:
fun()
函数可以简化,因为sort()
函数已经确保了不会出现相同的字母在同一循环中被比较。- 可以在外部循环中跳过已经使用过的字母,避免重复检查。
-
避免不必要的ASCII转换 :由于
str
已经降序排序,可以直接使用字母在数组中的索引来代替ASCII值减去'A'加上1的过程。 -
使用更有效的数据结构 :可以使用集合(如
std::set
)来存储已使用的字母,这样可以立即检查是否有重复的字母。 -
减少循环层数 :利用已排序的特性,一旦发现当前的
V
值无法通过剩余的字母组合满足等式,可以提前结束循环。 -
性能优化 :使用
std::next_permutation
来生成所有可能的排列,这样可以避免手动编写多层循环,并且自动处理唯一性问题。
HDU1016------Prime Ring Problem
题目描述
运行代码
cpp
#include <iostream>
#include <vector>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAX_N = 42;
vector<int> primes(MAX_N, 0);
vector<int> sequence;
vector<bool> visited(MAX_N, false);
void generate_prime_table() {
for (int i = 2; i <= MAX_N; ++i) {
if (primes[i] == 0) {
for (int j = i * 2; j <= MAX_N; j += i) {
primes[j] = 1;
}
}
}
}
void find_sequences(int current, int n) {
if (current == n) {
if (primes[sequence.front() + sequence.back()] == 0) {
for (size_t i = 0; i < sequence.size() - 1; ++i) {
cout << sequence[i] << " ";
}
cout << sequence.back() << '\n';
}
return;
}
for (int next = 2; next <= n; ++next) {
if (!visited[next] && primes[next + sequence.back()] == 0) {
visited[next] = true;
sequence.push_back(next);
find_sequences(current + 1, n);
sequence.pop_back();
visited[next] = false;
}
}
}
int main() {
generate_prime_table();
int case_num = 1;
int n;
while (cin>>n) {
cout << "Case " << case_num++ << ":\n";
sequence.clear();
fill(visited.begin(), visited.end(), false);
sequence.push_back(1);
find_sequences(1, n);
cout << '\n';
}
return 0;
}
代码思路
-
初始化质数表 :
generate_prime_table()
函数用于生成一个标记数组primes
,其中primes[i]
为0表示i
是质数,为1表示i
不是质数。这个函数使用筛法(Sieve of Eratosthenes)来填充这个数组。 -
寻找满足条件的序列:
find_sequences()
函数通过递归回溯的方法尝试构建满足条件的序列。- 当
current
等于n
时,意味着已经构建了一个长度为n
的序列。此时检查序列首尾数字的和是否为质数,如果不是,则输出这个序列。 - 对于每一个位置,尝试将还未使用过的数字
next
加入序列中,只要next
与序列末尾数字的和不是质数,就继续递归构建序列。
-
主函数逻辑:
- 首先调用
generate_prime_table()
生成质数表。 - 对于每一个测试用例
n
,清除之前的序列和访问标记,从数字1开始构建序列。 - 调用
find_sequences()
函数来寻找并输出所有满足条件的序列。
- 首先调用
代码的核心是深度优先搜索(DFS)结合回溯的思想。在构建序列的过程中,一旦发现当前路径(即当前构建的序列)不符合要求,就会回退(即pop_back和恢复visited状态),尝试下一个可能的数字。这种策略确保了所有可能的序列都被遍历,同时也避免了生成无效序列的冗余计算。