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

7 篇文章 0 订阅

目录

HDU1014——Uniform Generator

题目描述

运行代码

代码思路

HDU1015——Safecracker

题目描述

运行代码

代码思路

优化建议

HDU1016——Prime Ring Problem

题目描述

运行代码

代码思路

HDU1014——Uniform Generator

题目描述

Problem - 1014

运行代码

#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

运行代码

#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 == 0 和 str为"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

运行代码

#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状态),尝试下一个可能的数字。这种策略确保了所有可能的序列都被遍历,同时也避免了生成无效序列的冗余计算。

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

筱姌

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

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

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

打赏作者

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

抵扣说明:

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

余额充值