PTA光棍整除-C++

光棍整除
这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如,111111就可以被13整除。现在,你的程序要读入一个整数x,这个整数一定是奇数并且不以5结尾。然后,经过计算,输出两个数字:第一个数字s,表示x乘以s是一个光棍,第二个数字n是这个光棍的位数。这样的解当然不是唯一的,题目要求你输出最小的解。
提示:一个显然的办法是逐渐增加光棍的位数,直到可以整除x为止。但难点在于,s可能是个非常大的数 —— 比如,程序输入31,那么就输出3584229390681和15,因为31乘以3584229390681的结果是111111111111111,一共15个1。

输入格式:

输入在一行中给出一个不以5结尾的正奇数x(< 1000)。

输出格式:

在一行中输出相应的最小的s和n,其间以1个空格分隔。

输入样例:
31
输出样例:
3584229390681 15

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int main()
{
    int n,cnt=0,p=0;
    long long int ans=0;
    char a[10020];
    cin>>n;
    while (true){
        ans = ans*10+1;
        cnt++;
        if(p||ans/n)
        {
            printf("p=%d",p);
            a[p++] = ans/n+'0';
            printf("a[%d]=%c\n",p,a[--p]);
            ans%=n;
            if(ans==0){
                a[p]='\0';
                break;
            }
        }

    }
    printf("%s %d",a,cnt);
    return 0;
}
<think>根据用户的问题,用户想要在PTA平台上使用C++语言解决A-B问题。 但请注意,用户的问题中并没有明确A-B问题的具体含义。在编程竞赛中,常见的A-B问题可能是指两个数值的减法(但通常很简单),或者可能是指字符串的减法(如删除字符)等。 参考提供的引用[3],里面提到了一个A+B>C的问题,这类似于大数比较或整数溢出处理的问题。但用户现在询问的是A-B问题。 然而,在引用[1]中提到了哈希表(unordered_set)的使用,引用[2]和[3]都是关于PTA上的编程练习题解,其中引用[2]是C语言代码,引用[3]是C++代码,但处理的是A+B>C的问题。 由于用户明确要求使用C++语言,并且是在PTA平台上,我们需要考虑PTA平台常见的A-B问题题目。 常见的A-B问题有两种典型: 1. 数值减法:可能涉及大数或者溢出处理,类似于引用[3]中的A+B问题,但改为A-B。 2. 字符串处理:例如,给定两个字符串A和B,从字符串A中删除字符串B中出现的所有字符。 由于用户没有具体说明,而引用[1]又提到了哈希表,哈希表在字符串处理中非常有用。因此,我猜测用户可能指的是字符串的A-B问题(删除字符)。 下面我将提供两种可能的解决方法,并重点介绍使用哈希表处理字符串A-B问题的方法。 假设题目要求:输入两个字符串A和B,要求将字符串A中那些在字符串B中出现过的字符删掉,然后输出字符串A剩下的字符。 例如: 输入:字符串A="I am a student",字符串B="aeiou" 输出:字符串A处理后:"I m stdnt" (删除了所有元音字母) 方法一:使用哈希表(unordered_set)存储字符串B中的字符,然后遍历字符串A,若字符不在哈希表中则输出。 方法二:对于字符串B中的每个字符,使用循环在字符串A中查找并删除(效率较低,不推荐)。 下面给出使用C++的unordered_set实现的代码示例: ```cpp #include <iostream> #include <string> #include <unordered_set> using namespace std; int main() { string A, B; // 注意:PTA上的输入可能有空格,所以使用getline getline(cin, A); getline(cin, B); // 创建哈希集合,存储B中的字符 unordered_set<char> setB; for (char c : B) { setB.insert(c); } // 遍历A,如果字符不在集合中,则输出 for (char c : A) { if (setB.find(c) == setB.end()) { cout << c; } } cout << endl; // 题目可能要求输出后换行 return 0; } ``` 如果题目是数值减法(A-B),且可能涉及大数(超出long long范围)则需要用字符串模拟减法。但用户的问题中引用[1]提到了哈希表,所以更可能是字符串处理。 另外,考虑到引用[3]中处理了整数溢出的问题,如果用户指的是数值减法且可能溢出,那么解决方法类似于引用[3]中的加法比较,但改为减法。不过,减法溢出情况较为复杂,因为涉及正负。 但是,用户的问题明确是A-B,且要求C++,所以这里再提供一个处理整数减法且防止溢出的方法(如果题目要求类似大整数减法,则需用字符串或数组处理,但此处假设是普通整数): 题目可能要求:计算A-B,但A和B可能很大,导致溢出?实际上,在PTA平台,题目通常会给出数据范围。如果不会溢出,直接减即可。 例如,题目要求:输入两个整数A和B,输出A-B。 最简单的代码: ```cpp #include <iostream> using namespace std; int main() { long long A, B; // 如果题目数据范围大,用long long cin >> A >> B; cout << A - B << endl; return 0; } ``` 但是,如果题目要求处理超大整数(超过long long范围),则需要用字符串模拟减法(类似于大整数加法,但处理借位)。 由于用户的问题并不明确,且引用[1]提到了哈希表,因此我更倾向于字符串删除问题。但为了全面,下面再提供一个字符串表示的大整数减法的思路(代码较长,但也是PTA常见题): 大整数减法(两个非负整数,且A>=B)的步骤: 1. 用字符串存储两个数,并反转字符串(从个位开始处理)。 2. 从低位开始逐位相减,注意借位。 3. 处理结果的前导零。 代码示例(仅处理非负整数且A>=B的情况): ```cpp #include <iostream> #include <string> #include <algorithm> using namespace std; string bigSub(string a, string b) { // 确保a>=b if (a.length() < b.length() || (a.length() == b.length() && a < b)) { // 如果a<b,则交换并输出负号,这里题目可能要求非负,所以先不考虑 // 实际上,题目通常要求非负,所以这里只处理a>=b的情况 return "Error: A<B not supported"; } reverse(a.begin(), a.end()); reverse(b.begin(), b.end()); string res = ""; int carry = 0; // 借位 for (int i = 0; i < a.length(); i++) { int digitA = a[i] - '0'; int digitB = i < b.length() ? b[i] - '0' : 0; int temp = digitA - digitB - carry; if (temp < 0) { temp += 10; carry = 1; } else { carry = 0; } res.push_back(temp + '0'); } // 反转回来,并去掉前导零 reverse(res.begin(), res.end()); // 去除前导0 int start = 0; while (start < res.length() && res[start] == '0') { start++; } if (start == res.length()) return "0"; return res.substr(start); } int main() { string A, B; cin >> A >> B; cout << bigSub(A, B) << endl; return 0; } ``` 由于用户问题不明确,我提供了两种常见的情况。根据引用[1]中提到的哈希表,重点在第一种字符串删除问题。 用户可以根据具体题目要求选择相应的代码。 如果用户指的是其他问题,例如A-B问题的其他变种,请提供更具体的题目描述。 §§相关问题§§ 1. 哈希表在C++中的具体应用场景有哪些? 2. 如何用C++实现字符串的大整数加法? 3. 在PTA平台上遇到A-B问题,但题目描述不同,该如何处理? </think>根据您的查询,结合PTA平台特点和C++语言特性,以下是解决A-B问题的方法及关键要点分析: ### 一、A-B问题的常见类型与解法 在PTA平台中,A-B问题通常分为两种类型: 1. **数值减法问题**(整数/浮点数减法) - 核心挑战:处理**数据溢出**(如`int`范围$[-2^{31}, 2^{31}-1]$) - 解法:使用`long long`或`double`存储大数 ```cpp #include <iostream> using namespace std; int main() { long long A, B; // 防溢出 cin >> A >> B; cout << A - B << endl; return 0; } ``` 2. **字符串处理问题**(从A中删除B包含的字符) - 核心挑战:**高效删除指定字符** - 解法:使用哈希表(`unordered_set`)优化查找效率 ```cpp #include <iostream> #include <unordered_set> using namespace std; int main() { string A, B; getline(cin, A); getline(cin, B); unordered_set<char> setB(B.begin(), B.end()); // 哈希存储B的字符 for (char c : A) { if (!setB.count(c)) cout << c; // O(1)查找 } return 0; } ``` ### 二、关键实现技术 1. **哈希表优化**(引用[1]) - 时间复杂度:$O(1)$查找 vs 红黑树$O(\log n)$ - 适用场景:静态可预知数据,适合字符删除类问题 - 容器选择:`unordered_set`/`unordered_map` 2. **大数处理技巧**(引用[3]) - 当$|A-B| > 2^{31}$时: ```cpp if (A > 0 && B < 0 && A - B < 0) // 正减负导致负溢出 else if (A < 0 && B > 0 && A - B > 0) // 负减正导致正溢出 ``` 3. **输入输出规范**(引用[2][3]) - PTA要求严格匹配输出格式: ```cpp Case #1: [结果] ``` - 建议使用: ```cpp printf("Case #%d: %s\n", case_id, (A-B>0)?"true":"false"); ``` ### 三、推荐解决方案 根据PTA高频题型,建议优先采用**哈希表+大数防护**的复合方案: ```cpp #include <iostream> #include <unordered_set> #include <string> using namespace std; int main() { string A, B; getline(cin, A); getline(cin, B); // 哈希存储待删除字符 unordered_set<char> delSet(B.begin(), B.end()); // 过滤输出 for (char c : A) { if (delSet.find(c) == delSet.end()) { cout << c; } } return 0; } ``` > **复杂度分析**: > - 时间复杂度:$O(n+m)$,其中$n=|A|$, $m=|B|$ > - 空间复杂度:$O(m)$(哈希表存储) > - 优势:避免双重循环的$O(n \times m)$开销 ### 四、PTA平台注意事项 1. 必须包含标准头文件:`#include <iostream>` 2. 使用`using namespace std;`避免命名冲突 3. 输出**严格匹配**题目要求的空格/换行 4. 大数场景下优先使用`long long`代替`int` 如需处理具体题目变体(如带空格输入或多组数据),请提供题目编号或详细描述以便进一步优化代码[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值