【算数基本定理(唯一分解定理)】Aladdin and the Flying Carpet LightOJ - 1341

本文介绍算数基本定理的应用及如何利用该原理解决特定数学问题,包括求解一个矩形面积为a且最短边长至少为b时,满足条件的非正方形矩形数量。

Think:
1知识点:算数基本定理(唯一分解定理)
算术基本定理的几个应用:

注:p1, p2, pi都是素数
同时全体正因数的和也可以写作:

——“算数基本定理”参考博客地址

2题意:输入a, b(1 ≤ b ≤ a ≤ 1e12),a代表一个矩形的面积,b表示矩形中最小的那条边至少长度为b,询问有多少个符合条件的矩形
注:题意要去本题目中的矩形不是正方形
3解题思路:
通过算数基本定理求得a的所有正因数数量,除以2(求解符合情况的矩形),然后减去所有小于b的正因数的数量
4反思:
(1):判断条件b*b > a应转化为判断条件b > a/b,进而避免越界
(2):通过素数筛得到素数表后,在分解tmp时,可以通过(LL)link[i]*(LL)link[i]优化剪枝(未剪枝之前2312ms+,剪枝之后344ms+)

vjudge题目链接

以下为Accepted代码——344ms

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int size1 = 1004014;

bool primes[size1];
int tp, link[size1];

void get_primes();

int main(){
    get_primes();
    int k = 1, T, cnt, num;
    LL a, b, tmp;
    scanf("%d", &T);
    while(T--){
        scanf("%lld %lld", &a, &b);
        if(b >= a/b){
            printf("Case %d: 0\n", k++);
            continue;
        }
        num = 1, tmp = a;
        for(int i = 0; i < tp && (LL)link[i]*(LL)link[i] <= tmp; i++){
            if(tmp%link[i] == 0){
                cnt = 0;
                while(tmp%link[i] == 0){
                    cnt++;
                    tmp /= link[i];
                }
                num *= (cnt+1);
            }
            if(tmp < link[i]) break;
        }
        if(tmp != 1){
            num <<= 1;
        }
        num >>= 1;
        for(int i = 1; i < b; i++){
            if(a%i == 0) num--;
        }
        printf("Case %d: %d\n", k++, num);
    }
    return 0;
}
void get_primes(){
    tp = 0;
    memset(primes, 0, sizeof(primes));
    primes[0] = 1;
    for(LL i = 2; i < size1; i++){
        if(!primes[i]){
            for(LL j = i*i; j < size1; j += i){
                primes[j] = 1;
            }
            link[tp++] = i;
        }
    }
    return;
}
<think>我们正在处理一个关于find命令与-exec参数结合bash -c使用mv命令重命名文件不生效的问题。 用户可能尝试了类似这样的命令: find . -type f -exec bash -c 'mv "$0" "${0%.*}.txt"' {} \; 但发现没有按预期重命名文件。 我们需要分析可能的原因: 1. 路径中包含空格或特殊字符:在bash -c中,如果文件名包含空格,使用$0只能获取到第一个单词,导致错误。 正确做法是使用"$1"并传递带引用的参数,或者使用位置参数。 2. 命令语法错误:在bash -c中,我们通常使用位置参数($1, $2等)来接收参数,因为{}被传递给bash -c作为参数。 3. 当前目录与文件所在目录:如果文件不在当前目录,相对路径可能有问题。 4. 权限问题:可能没有写权限。 5. 目标文件已存在:mv命令在目标存在时可能不会覆盖(除非使用-f,但这里没有)。 根据用户描述,问题很可能出在参数传递上。我们应建议使用以下方式: find . -type f -exec bash -c 'mv "$1" "${1%.*}.txt"' _ {} \; 解释: - 在bash -c后面的字符串中,我们使用一个占位符(通常用'_')作为第0个参数(即脚本名),然后{}作为第一个参数($1)传入。 - 这样,在bash -c命令内部,我们使用$1来引用文件名,并用引号括起来以处理空格。 另一种方法是使用+来传递多个文件,但注意在重命名时,我们通常一次操作一个文件,因为每个文件的重命名目标不同。 但是,如果用户希望一次处理多个文件(例如,使用循环),那么我们可以使用: find . -type f -exec bash -c 'for f; do mv "$f" "${f%.*}.txt"; done' bash {} + 这里,我们使用for循环遍历所有参数(for f; 相当于 for f in "$@";),然后逐个重命名。 然而,用户的问题描述中并没有提到一次处理多个文件,所以我们先提供第一种解决方案。 另外,注意用户可能想修改文件扩展名为.txt,但原命令中${0%.*}会去掉文件的扩展名,然后加上.txt。如果原文件有多个扩展名,这可能会出问题(比如file.tar.gz会变成file.tar.txt)。但这是用户期望的操作,所以按此执行。 因此,我们给出两个建议的修正命令。 同时,我们也要注意引用[1]中关于exec的说明:在bash中,exec可以替换当前shell,但在这里我们使用的是find的-exec,它是find的一个参数,用于执行命令。而引用[1]中描述的是bash内建命令exec,与find的-exec不同。不过,我们这里的问题与bash内建exec无关。 另外,引用[2]是关于docker的,与当前问题无关。 所以,我们忽略引用[1]和引用[2],直接针对问题回答。 步骤: 1. 解释问题可能的原因。 2. 给出修正后的命令。 3. 解释命令的工作原理。 注意:由于用户要求使用中文回答,并且生成相关问题,我们按照要求进行。</think>### 解决 `find` 命令中 `-exec` 结合 `bash -c` 重命名失败的问题 您遇到的 `find -exec bash -c mv` 重命名失败问题,通常由 **参数传递格式错误** 或 **文件名特殊字符处理不当** 导致。以下是修正方案: #### ✅ 修正后的命令(推荐方案) ```bash find . -type f -exec bash -c 'mv -v "$1" "${1%.*}.txt"' _ {} \; ``` #### 🔍 关键修正说明: 1. **参数传递修正** `bash -c` 的第一个参数(`$0`)是脚本名,实际文件路径应从 `$1` 开始访问: ```bash # 错误:$0 指向无效参数(通常是 "bash" 本身) bash -c 'mv "$0" ...' # 正确:用占位符 "_" 跳过 $0,文件路径通过 $1 传递 bash -c 'mv "$1" ...' _ {} ``` 2. **引号保护特殊字符** 文件名中的空格、括号等需用双引号包裹: ```bash mv "$1" ... # ✅ 正确处理含空格的文件名 mv $1 ... # ❌ 空格会导致路径被拆分为多个参数 ``` 3. **扩展名修改逻辑** `${1%.*}` 会移除原文件扩展名(如 `file.jpg` → `file`),再追加 `.txt`。 --- #### ⚙️ 进阶用法:批量处理多个文件 ```bash find . -type f -exec bash -c ' for file; do mv -- "$file" "${file%.*}.txt" done ' _ {} + ``` - `{} +` 替代 `{} \;` 可减少进程创建次数,提升效率 - `for file; do ... done` 循环处理所有匹配文件 - `--` 确保以 `-` 开头的文件名不被识别为选项 --- #### ❓ 常见失败原因排查 1. **权限问题** 检查目标目录是否有写权限:`ls -ld /path/to/dir` 2. **目标文件已存在** `mv` 默认不覆盖,可添加 `-f` 强制覆盖(谨慎使用) 3. **路径错误** 用 `-print` 先预览匹配文件: `find . -type f -print` --- ### 相关问题 1. 如何用 `find` 命令批量修改文件名中的特定字符串? 2. `find -exec` 与 `xargs` 在处理文件名时有何优劣? 3. 如何避免 `mv` 命令因文件名特殊字符(如空格、引号)导致的错误? [^1]: shell编程 - Bash Builtins General Commands Manual
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值