HDU1014——Uniform Generator,HDU1015——Safecracker,HDU1016——Prime Ring Problem

目录

[HDU1014------Uniform Generator](#HDU1014——Uniform Generator)

题目描述

运行代码

代码思路

HDU1015------Safecracker

题目描述

运行代码

代码思路

优化建议

[HDU1016------Prime Ring Problem](#HDU1016——Prime Ring Problem)

题目描述

运行代码

代码思路

HDU1014------Uniform Generator

题目描述

Problem - 1014

运行代码

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;
}

代码思路

  1. 定义Choice函数

    • 接收两个整数参数stepmod
    • 创建一个布尔型数组visited,用于标记0到mod-1之间的每个数是否已被访问。
    • 初始化visited数组,将所有元素设为false
    • cur = 0开始,按step步长进行移动,使用模运算保证cur始终在0到mod-1范围内。
    • 每次移动都将cur位置标记为已访问,然后更新cur的值。
    • 最后,遍历visited数组,检查是否有未被访问的位置。
    • 如果所有位置都被访问过,则返回true,表示这是个好的选择;否则返回false
  2. main函数

    • 读取标准输入中的stepmod,直到没有更多输入为止。
    • 使用cout的宽度设置和右对齐功能来格式化输出,使得输出更加整齐。
    • 调用Choice函数,根据返回值判断并输出是"Good Choice"还是"Bad Choice"。

HDU1015------Safecracker

题目描述

Problem - 1015

运行代码

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;
}

代码思路

  1. 函数定义fun()函数用于检查五个字母是否互不相同。cmp()函数用于降序排序字母。

  2. 主函数逻辑

    • 循环读取输入直到遇到终止条件(n == 0str为"END")。
    • 将输入的字符串str降序排序。
    • 使用五层嵌套循环遍历所有可能的五字母组合。
    • 使用fun()函数检查字母是否互不相同。
    • 如果满足条件,计算等式左侧的值,并与给定的整数n比较。
    • 如果等式成立,打印出这组字母并退出所有循环。
    • 如果遍历结束后仍未找到满足条件的组合,输出"no solution"。

优化建议

  1. 减少不必要的比较

    • fun()函数可以简化,因为sort()函数已经确保了不会出现相同的字母在同一循环中被比较。
    • 可以在外部循环中跳过已经使用过的字母,避免重复检查。
  2. 避免不必要的ASCII转换 :由于str已经降序排序,可以直接使用字母在数组中的索引来代替ASCII值减去'A'加上1的过程。

  3. 使用更有效的数据结构 :可以使用集合(如std::set)来存储已使用的字母,这样可以立即检查是否有重复的字母。

  4. 减少循环层数 :利用已排序的特性,一旦发现当前的V值无法通过剩余的字母组合满足等式,可以提前结束循环。

  5. 性能优化 :使用std::next_permutation来生成所有可能的排列,这样可以避免手动编写多层循环,并且自动处理唯一性问题。

HDU1016------Prime Ring Problem

题目描述

Problem - 1016

运行代码

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;
}

代码思路

  1. 初始化质数表generate_prime_table()函数用于生成一个标记数组primes,其中primes[i]为0表示i是质数,为1表示i不是质数。这个函数使用筛法(Sieve of Eratosthenes)来填充这个数组。

  2. 寻找满足条件的序列

    • find_sequences()函数通过递归回溯的方法尝试构建满足条件的序列。
    • current等于n时,意味着已经构建了一个长度为n的序列。此时检查序列首尾数字的和是否为质数,如果不是,则输出这个序列。
    • 对于每一个位置,尝试将还未使用过的数字next加入序列中,只要next与序列末尾数字的和不是质数,就继续递归构建序列。
  3. 主函数逻辑

    • 首先调用generate_prime_table()生成质数表。
    • 对于每一个测试用例n,清除之前的序列和访问标记,从数字1开始构建序列。
    • 调用find_sequences()函数来寻找并输出所有满足条件的序列。

代码的核心是深度优先搜索(DFS)结合回溯的思想。在构建序列的过程中,一旦发现当前路径(即当前构建的序列)不符合要求,就会回退(即pop_back和恢复visited状态),尝试下一个可能的数字。这种策略确保了所有可能的序列都被遍历,同时也避免了生成无效序列的冗余计算。

相关推荐
single59425 分钟前
【c++笔试强训】(第四十五篇)
java·开发语言·数据结构·c++·算法
呆头鹅AI工作室1 小时前
基于特征工程(pca分析)、小波去噪以及数据增强,同时采用基于注意力机制的BiLSTM、随机森林、ARIMA模型进行序列数据预测
人工智能·深度学习·神经网络·算法·随机森林·回归
一勺汤2 小时前
YOLO11改进-注意力-引入自调制特征聚合模块SMFA
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·目标跟踪
每天写点bug2 小时前
【golang】map遍历注意事项
开发语言·算法·golang
程序员JerrySUN2 小时前
BitBake 执行流程深度解析:从理论到实践
linux·开发语言·嵌入式硬件·算法·架构
王老师青少年编程3 小时前
gesp(二级)(16)洛谷:B4037:[GESP202409 二级] 小杨的 N 字矩阵
数据结构·c++·算法·gesp·csp·信奥赛
robin_suli3 小时前
动态规划子序列问题系列一>等差序列划分II
算法·动态规划
cxylay4 小时前
自适应滤波算法分类及详细介绍
算法·分类·自适应滤波算法·自适应滤波·主动噪声控制·anc
茶猫_4 小时前
力扣面试题 - 40 迷路的机器人 C语言解法
c语言·数据结构·算法·leetcode·机器人·深度优先
轻浮j5 小时前
Sentinel底层原理以及使用算法
java·算法·sentinel