PAT[乙级]1021-1025
1021 个位数统计 (15 分) [字符串处理]
题目描述
代码
#include <bits/stdc++.h>
using namespace std;
string s;
int num[10];//存储字符串的个数
int main() {
cin >> s;
for(int i = 0 ; i<s.length() ; i++)
num[s[i]-'0']++;//数组下标法的经典应用
for(int i = 0 ; i<10 ; i++)
if(num[i])
cout<<i<<":"<<num[i]<<endl;
return 0;
}
1022 D进制的A+B (20 分)[进制转换]
题目描述
输⼊两个⾮负10进制整数A和B
(
<
=
2
30
−
1
)
(<=2^{30}-1)
(<=230−1),输出A+B的D (1 < D <= 10)进制数。
输⼊格式:
输⼊在⼀⾏中依次给出3个整数A、B和D。
输出格式:
输出A+B的D进制数。
输⼊样例:
123 456 8
输出样例:
1103
代码
#include <iostream>
using namespace std;
int main() {
long long a,b;
cin >> a >> b;
long long c = a + b;
int d;
cin >> d;
string s;
if(!c)//若为0直接输出
cout << 0;
while(c) {//进制转换
s += c%d + '0';
c /= d;
}
for(int i = s.size()-1 ; i >= 0 ; --i)
cout << s[i];
return 0;
}
分析:
设c= a +b
,将每⼀次c%d
的结果保存在字符串s
中,然后将c/ d
,直到 c 等于 0
为⽌此时s中保存的就是 c在 D 进制下每⼀位的结果的倒序,最后倒序输出s即可
1023 组个最小数 (20 分)[字符串处理]
题目描述
给定数字 0-9 各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意 0 不能做首位)。例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最小的数就是 10015558。
现给定数字,请编写程序输出能够组成的最小的数。
输入格式:
输入在一行中给出 10 个非负整数,顺序表示我们拥有数字 0、数字 1、……数字 9 的个数。整数间用一个空格分隔。10 个数字的总个数不超过 50,且至少拥有 1 个非 0 的数字。
输出格式:
在一行中输出能够组成的最小的数。
输入样例:
2 2 0 0 0 3 0 0 1 0
输出样例:
10015558
#include <iostream>
#include <string>
using namespace std;
int cnt[10];
int main() {
cin >> cnt[0];
string s;
//先不处理0,从1开始遍历
for(int i = 1 ; i < 10 ; ++i) {
cin >> cnt[i];
while(cnt[i]--)
s += i + '0';
}
while(cnt[0]--)
s.insert(1,"0");
cout << s;
return 0;
}
分析:
- 我 们 可 以 先 不 处 理 0 , 从 1 开 始 遍 历 组 成 一 个 非 0 的 最 小 数 ( 按 照 顺 序 一 次 存 入 字 符 串 s 中 即 可 ) 我们可以先不处理0,从1开始遍历组成一个非0的最小数(按照顺序一次存入字符串s中即可) 我们可以先不处理0,从1开始遍历组成一个非0的最小数(按照顺序一次存入字符串s中即可)
- 然 后 在 s [ 1 ] 的 位 置 插 入 0 , 有 多 少 个 插 入 多 少 个 然后在s[1]的位置插入0,有多少个插入多少个 然后在s[1]的位置插入0,有多少个插入多少个
代码
1024. 科学计数法 (20) [字符串处理]
题目描述
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [±][1-9].
[0-9]+E[±][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。
现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。
输入格式:
每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。
输出格式:
对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。
输入样例 1:
+1.23400E-03
输出样例 1:
0.00123400
输入样例 2:
-1.2E+10
输出样例 2:
-12000000000
代码
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main() {
string s;
cin >> s;
int k = s.find("E");
int a = stoi(s.substr(k+1));//指数部分
s.erase(k);//清除包含E后面的字符
int len = s.size() - 3;//获得'.'之后数字的长度
s.erase(2,1);//清除'.'号
if(a > 0) {//指数大于0
if(a >= len) {//指数大于等于'.'之后数字的长度,就不需要有'.',只需要在后面舔0即可
for(int i = len ; i < a ; ++i){
s.insert(s.size(),"0");
}
} else {//指数小于'.'之后数字的长度,就需添加'.'号
s.insert(2 + a , ".");
}
}else {//指数小于0
for(int i = 0 ; i < abs(a) ; ++i) {
s.insert(1,"0");//插入a个0
}
s.insert(2,".");//由于前面还有符号,所以在2的位置上插入'.'号
}
if(s[0] == '+') {//清除'+'号
s.erase(0,1);
}
cout << s;
return 0;
}
思路:
- 整 体 的 操 作 都 是 在 一 个 字 符 串 中 操 作 整体的操作都是在一个字符串中操作 整体的操作都是在一个字符串中操作
- 先 定 位 ′ E ′ , 找 到 指 数 部 分 , 并 把 指 数 部 分 变 成 小 数 ( 截 取 字 串 , 然 后 转 为 整 数 , , 负 数 也 要 弄 进 去 ) 先定位'E',找到指数部分,并把指数部分变成小数(截取字串,然后转为整数,,负数也要弄进去) 先定位′E′,找到指数部分,并把指数部分变成小数(截取字串,然后转为整数,,负数也要弄进去)
- 清 除 包 含 ′ E ′ 后 面 的 字 符 以 便 后 面 的 操 作 清除包含'E'后面的字符以便后面的操作 清除包含′E′后面的字符以便后面的操作
- 获 得 ′ . ′ 之 后 数 字 的 长 度 , 目 的 是 知 道 原 数 字 有 多 少 位 小 数 获得'.'之后数字的长度,目的是知道原数字有多少位小数 获得′.′之后数字的长度,目的是知道原数字有多少位小数
- 按 照 指 数 大 于 0 , 小 于 0 来 分 别 处 理 按照指数大于0,小于0来分别处理 按照指数大于0,小于0来分别处理
1025 反转链表 (25 分)[链表]
题目描述
给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转。例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4;如果 K 为 4,则输出应该为 4→3→2→1→5→6,即最后不到 K 个元素不反转。
输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (
≤
1
0
5
≤10 ^5
≤105)、以及正整数 K (≤N),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address
是结点地址,Data
是该结点保存的整数数据,Next
是下一结点的地址。
输出格式:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
输入样例:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
代码
/*思路:利用数组来存储数据和结点的地址*/
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100005;
int main() {
int first , k , n , temp;
int data[N] , next[N] , list[N];
/*
data[] : 存储输入的数据
next[] : 存储输入的下一个结点的地址
list[] : 按照输入头结点的地址顺序的存储当前结点的地址
*/
cin >> first >> n >> k;
for(int i = 0 ; i < n ; ++i) {
cin >> temp;
cin >> data[temp] >> next[temp];
}
int sum = 0;
while(first != -1) {//当前结点的地址为-1则为空
list[sum++] = first;
first = next[first];
}
for(int i = 0 ; i < (sum - sum % k) ; i += k) {//按照要求排序
reverse(begin(list) + i , begin(list) + i + k);
}
for(int i = 0 ; i < sum - 1 ; ++i) {
printf("%05d %d %05d\n",list[i],data[list[i]],list[i + 1]);
}
//当下一个结点的地址为空时,list[]不存储其结点地址
printf("%05d %d -1", list[sum - 1], data[list[sum - 1]]);
return 0;
}