1096. Consecutive Factors (20)——PAT (Advanced Level) Practise

寻找连续因子
本文介绍了一种算法,用于找出正整数N的最大连续因子序列,并列出这些连续因子。通过递归深度优先搜索的方法来查找所有可能的连续因子组合,并选择最长序列。

题目信息

1096. Consecutive Factors (20)

时间限制400 ms
内存限制65536 kB
代码长度限制16000 B
Among all the factors of a positive integer N, there may exist several consecutive numbers. For example, 630 can be factored as 3*5*6*7, where 5, 6, and 7 are the three consecutive numbers. Now given any positive N, you are supposed to find the maximum number of consecutive factors, and list the smallest sequence of the consecutive factors.

Input Specification:

Each input file contains one test case, which gives the integer N (1

解题思路

分奇偶两种情况讨论

AC代码

#include <algorithm>
#include<set>
#include<queue>
#include<map>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;

void dfsFactor(long long n, long long preNum, vector<int>&factor, vector<vector<int>>&ans,int&factorSize)
{
    if (n % (preNum + 1) == 0)
    {
        factor.push_back(preNum + 1);
        dfsFactor(n / (preNum + 1), preNum + 1, factor, ans, factorSize);
    }
    else if (!factor.empty() && factor.size() > factorSize)
    {
        factorSize = factor.size();
        ans.push_back(factor);
    }
}
bool cmp(const vector<int>&a, const vector<int>&b)
{
    if (a.size() > b.size())
        return true;
    else if (a.size() == b.size() && a[0] < b[0])
        return true;
    else return false;
}
int main(void)
{
    int n;
    cin >> n;
        if (n % 2 == 1)
        {
            int temp = (int)((double)sqrt(n) + 1);
            for (int i = 2; i <= temp; ++i)
            {
                if (n%i == 0)
                {
                    cout << "1" << endl;
                    cout << i << endl;
                    return 0;
                }
            }
            cout << "1" << endl;
            cout << n << endl;

        }
        else
        {
            vector<int> maxFactor = { INT_MAX, n, (int)((double)sqrt(n) + 1), 1290, 215, 73, 35, 21, 14, 10, 0 };//3~13
            vector<int> factor(0);
            vector<vector<int>>ans(0);
            int factorSize = 0;

            for (long long i = 1; i <= min(n, maxFactor[factorSize + 1]); i++)
            {
                if (n % (i + 1) == 0)
                {
                    dfsFactor(n, i, factor, ans, factorSize);
                    factor.clear();
                }
            }
            sort(ans.begin(), ans.end(), cmp);
            cout << ans[0].size() << endl;
            for (int i = 0; i < ans[0].size(); i++)
            {
                cout << ans[0][i];
                if (i != ans[0].size() - 1)
                    cout << "*";
            }
            cout << endl;
        }
    return 0;
}
这个提示 `Detected consecutive bitfield assigns. Recommend using bit mask instead` 通常出现在 C/C++ 编译器或静态分析工具中,它指出你连续多次对结构体中的 **bit field(位域)** 成员进行了赋值操作,建议改用 **位掩码(bitmask)** 操作来提高效率和避免潜在的并发问题。 --- ## 一、什么是 Bitfield? Bitfield 是一种在结构体中定义变量时指定其占用位数的机制,常用于硬件寄存器访问、协议解析等场景。例如: ```c struct { unsigned int enable : 1; // 占1位 unsigned int mode : 3; // 占3位 unsigned int value : 4; // 占4位 } config; ``` --- ## 二、为什么连续赋值不推荐? 当你这样写代码时: ```c config.enable = 1; config.mode = 2; config.value = 5; ``` 由于每个字段可能属于同一个字节或字,编译器需要进行多次内存访问和掩码操作,这可能导致性能下降,尤其是在嵌入式系统中频繁操作寄存器时。而且如果这些操作发生在中断上下文或者多线程环境中,还可能引发竞态条件。 --- ## 三、使用 bitmask 替代 我们可以通过直接操作整个整型变量的方式来设置多个位域字段。例如上面的结构体可以映射成一个 8 位的整型: ```c typedef union { struct { uint8_t enable : 1; uint8_t mode : 3; uint8_t value : 4; }; uint8_t all; } ConfigReg; ``` 然后我们可以一次性设置所有字段: ```c ConfigReg reg; reg.all = (1 << 0) | (2 << 1) | (5 << 4); ``` ### ✅ 优点: - 只有一次内存写入操作 - 避免了多次结构体成员访问 - 更加适合底层硬件编程 --- ## 四、完整示例代码 ```c #include <stdio.h> #include <stdint.h> typedef union { struct { uint8_t enable : 1; uint8_t mode : 3; uint8_t value : 4; }; uint8_t all; } ConfigReg; int main() { ConfigReg reg; // 使用 bitmask 一次性设置所有字段 reg.all = (1 << 0) | (2 << 1) | (5 << 4); printf("enable: %u\n", reg.enable); printf("mode: %u\n", reg.mode); printf("value: %u\n", reg.value); printf("all: 0x%02X\n", reg.all); return 0; } ``` --- ## 五、解释说明 - 使用 `union` 将位域和整体访问统一起来。 - `(1 << 0)` 设置 enable 为 1。 - `(2 << 1)` 表示 mode 字段从第 1 位开始。 - `(5 << 4)` 表示 value 字段从第 4 位开始。 - 所有字段通过一次赋值完成设置,避免了多次 bitfield 赋值的问题。 --- ## 六、注意事项 - 不同平台对 bitfield 的布局顺序(高位在前还是低位在前)可能不同,因此在跨平台开发中应谨慎使用。 - 使用 bitmask 可以更精确地控制数据布局,更适合嵌入式开发。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值