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) (<=2301),输出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;
}

分析:

  1. 我 们 可 以 先 不 处 理 0 , 从 1 开 始 遍 历 组 成 一 个 非 0 的 最 小 数 ( 按 照 顺 序 一 次 存 入 字 符 串 s 中 即 可 ) 我们可以先不处理0,从1开始遍历组成一个非0的最小数(按照顺序一次存入字符串s中即可) 0,10(s)
  2. 然 后 在 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;
}

思路:

  1. 整 体 的 操 作 都 是 在 一 个 字 符 串 中 操 作 整体的操作都是在一个字符串中操作
  2. 先 定 位 ′ E ′ , 找 到 指 数 部 分 , 并 把 指 数 部 分 变 成 小 数 ( 截 取 字 串 , 然 后 转 为 整 数 , , 负 数 也 要 弄 进 去 ) 先定位'E',找到指数部分,并把指数部分变成小数(截取字串,然后转为整数,,负数也要弄进去) E,,(,,,)
  3. 清 除 包 含 ′ E ′ 后 面 的 字 符 以 便 后 面 的 操 作 清除包含'E'后面的字符以便后面的操作 E便
  4. 获 得 ′ . ′ 之 后 数 字 的 长 度 , 目 的 是 知 道 原 数 字 有 多 少 位 小 数 获得'.'之后数字的长度,目的是知道原数字有多少位小数 .,
  5. 按 照 指 数 大 于 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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值