Aladdin and the Flying Carpet LightOJ - 1341(算数基本定理)

探讨了Aladdin使用特定面积及最小边长条件下的矩形飞行地毯通过洞穴入口的可能性数量。通过筛选质数并利用算术基本定理解决这一问题。

Aladdin and the Flying Carpet

LightOJ - 1341

It's said that Aladdin had to solve seven mysteries before getting the Magical Lamp which summons a powerful Genie. Here we are concerned about the first mystery.

Aladdin was about to enter to a magical cave, led by the evil sorcerer who disguised himself as Aladdin's uncle, found a strange magical flying carpet at the entrance. There were some strange creatures guarding the entrance of the cave. Aladdin could run, but he knew that there was a high chance of getting caught. So, he decided to use the magical flying carpet. The carpet was rectangular shaped, but not square shaped. Aladdin took the carpet and with the help of it he passed the entrance.

Now you are given the area of the carpet and the length of the minimum possible side of the carpet, your task is to find how many types of carpets are possible. For example, the area of the carpet 12, and the minimum possible side of the carpet is 2, then there can be two types of carpets and their sides are: {2, 6} and {3, 4}.


Input

Input starts with an integer T (≤ 4000), denoting the number of test cases.

Each case starts with a line containing two integers: a b (1 ≤ b ≤ a ≤ 1012) where a denotes the area of the carpet and b denotes the minimum possible side of the carpet.

Output

For each case, print the case number and the number of possible carpets.

Sample Input

2

10 2

12 2

Sample Output

Case 1: 1

Case 2: 2

算术基本定理又叫唯一分解定理。
算术基本定理内容:任何一个大于1的自然数 ,都可以唯一分解成有限个质数的乘积 这里写图片描述 ,这里 这里写图片描述均为质数,其中指数 ai是正整数。


算术基本定理的几个应用:
下面的p1,p2…pn都是素数。
这里写图片描述

同时全体正因数的和也可以写作:
这里写图片描述


本题就是第一个应用。
有几个注意的地方:获得质数的个数的时候,可以先不筛选素数,但是本题时间卡的紧,必须要先筛素数。还有注意当b*b>=a的时候就特判。


最后把总的个数除2然后减去因数小于要求的最小因数的情况

code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int MAXN = 1e6+10;
int t;
int primes[MAXN];
bool isprime[MAXN];
void getPrime(){
    memset(isprime,true,sizeof(isprime));
    isprime[0] = isprime[1] = false;
    t = 0;
    for(int i = 2; i < MAXN; i++){
        if(isprime[i]){
            primes[t++] = i;
            for(int j = i + i; j < MAXN; j += i){
                isprime[j] = false;
            }
        }
    }
    return;
}
int getfac(ll x){
    int ans = 1;
    for(int i = 0; i < t && primes[i] * primes[i] <= x; i++){
        if(x == 1) break;
        int tmp = 0;
        while(x % primes[i] == 0){
            tmp++;
            x /= primes[i];
        }
        ans *= (tmp + 1);
    }
    if(x != 1) ans *= 2;//ans = ans * (1 + 1);
    return ans;
}
int main(){
    getPrime();
    int t;
    int cas = 0;
    scanf("%d",&t);
    while(t--){
        ll a,b;
        scanf("%lld%lld",&a,&b);
        if(b * b >= a){//因为题目要求不是正方形,并且另一条边一定大于b
            printf("Case %d: 0\n",++cas);
            continue;
        }
        int ans = getfac(a);
        ans /= 2;//因子对,所以除2
        for(int i = 1; i < b; i++){
            if(a % i == 0) ans--;//将小于要求的最小因数的情况去掉
        }
        printf("Case %d: %d\n",++cas,ans);
    }
    return 0;
}


<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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值