PAT(乙级)2021年秋季考试7-1 好数 7-2 数以类聚 map容器暴力7-3 自定义判题程序 字符串处理7-4 数组与链表 前缀和7-5 取帽子 排序

7-1 好数 暴力

""a<b 按照 a^2+a*b+b^2""  由题意可得 a<b 且a*a<t 不可能等于 因为等于的时候解出来a*b为负数   按照a从1到a*a<t的  和 b=a+1起始到b*b<t 开始暴力 找到就输出 如果没有输出过就代表t不是好数  然后转向求大于t的最小好数  然后求该数的每一个来源 跟上面格式相同

#include<bits/stdc++.h>
using namespace std;
int main(void) {
	int n, t;
	cin >> n;
	for (int i = 0; i < n; ++i) {
		cin >> t;
		bool f = 1;
		for (int a = 1; a * a < t; ++a)
			for (int b = a + 1; b * b < t; ++b)
				if (a * a + a * b + b * b == t) {
					if (f) {
						printf("Yes\n");
						f = 0;
					}
					printf("%d %d\n", a, b);
				}
		if (f) {
			bool F = 0;
			printf("No ");
			for (++t;; ++t) {
				for (int a = 1; a * a < t; ++a) {
					for (int b = a + 1; b * b < t; ++b) {
						if (a * a + a * b + b * b == t) {
							F = 1;
							printf("%d\n", t);
							for (int a1 = 1; a1 * a1 < t; ++a1)
								for (int b2 = a1+1; b2 * b2 < t; ++b2)
									if (a1 * a1 + a1 * b2 + b2 * b2 == t) printf("%d %d\n", a1, b2);
							break;
						}
					}
					if (F) break;
				}
				if (F) break;
			}
		}
	}
	return 0;
}

7-2 数以类聚 map容器

""输出 N 个给定的整数可以归类的数量、以及规模最大的类中最小的乘积""  用map容器进行归类

max代表最大分类数量 num代表最大分类中最小的数

#include<bits/stdc++.h>
using namespace std;
int main(void) {
	int n, t, max = 0, num = 10000000;
	cin >> n;
	map<int, int> m;
	for (int i = 0; i < n; ++i) {
		cin >> t;
		int sum = 1;
		while (t) {
			sum *= t % 10;
			t /= 10;
		}
		++m[sum];
		if (m[sum] > max) {
			max = m[sum];
			num = sum;
		}
		if (m[sum] == max && sum < num)
			num = sum;
	}
	printf("%d %d", m.size(), num);
	return 0;
}

7-3 自定义判题程序 字符串处理

  • 如果这个字符不变,则在对应位置输出 0
  • 如果这个字符被删除,则在对应位置输出 1
  • 如果这个字符被改变,则在对应位置输出 2
  • 如果这个字符前面或者后面插入了一个字符,则在插入的位置输出 3

思路

        先检测是否含有空格 若有则WC 若无则检测是否k等于非数字的数量 若不等于则WC 若等于则开始按照给出的数字对原始字符串进行操作   创建一个指针变量l1指向当前要进行处理的原始字符串的字符下标   len为""描述对初始字符串的每个字符所做的操作:""序列的长度 j从0到len-1开始遍历 j指向当前要对字符串进行操作的数

02330001100022100过程如下:

string b="";

 s1: This is a test.

s2: Tom is a cat.

     此时l1为T  , 此时给出的处理数字为j指向0 , 0保留T b.push_back(s1[l1++]) ,, l1记得++  代表当前字符已经处理完毕 要换到下一个字符进行处理 , 同时j++

    此时l1为h 此时j指向2   2代表改变,则h变成o  为什么是变o呢? 因为当前b为"T" (因为上一轮刚入了一个T)  接下来对照目标字符串""Tom is a cat.""  T后面应是o  所以h变o   那代码怎么写呢?

b.push_back(s2[b.length()]);  此时j++  l1++ 开始处理下一个字符

     此时l1指向字符i   此时j指向3  3代表这个位置添加了一个字符 那我们就添加一个字符,代码如下

b.push_back(s2[b.length()]);  发现是不是跟上文代码一致?  因为现在b="To"  对照目标字符串  ""Tom is a cat.""  此时应该写入m,,所以写入m   加入字符完毕后j需要++吗?  需要因为当前指令已经处理完毕   l1需要++吗?大可不需要!!!因为l1对应的字符i不是0(保留)不是2(修改)不是1(丢弃)而是3(前面加了字符)  只是前面加上了字符  自己还没有被处理

     此时 l1指向字符i   因为上次没有对字符i进行处理只是在其前面加上了字符  其本身还没有进行任何处理  然后此时j指向3  然后又在其前面加上了个空格字符 " "   j++

      此时l1指向字符i   j指向命令0   0为保留则保留i   代码为  b.push_back(s1[l1++]);  j++

      ,,,,,,,,以此类推

注意点:

                对于用户输出的 K,如果其操作序列的确给出了 K 步操作并可以完成字符串的变换,则称为一个“可行解”。所谓“正确提交”,是指所有提交的可行解中的最优解。

        题目让你输出k最小的可行解  如果一个解的k为10  经过10此处理后原始字符串变成了目标字符串,则代表此k为10的解是一个可行解 但是如果另一个可行解的k为9   9是比10小的,用了更少的步骤得到了目标字符串   则k为9的解成为  正确提交     题目就是让你找k最小的解,对于这些k最小的解(们)  输出AC  其余只要k大于最小k的可行解都要输出WC

#include<bits/stdc++.h>
using namespace std;
int main(void) {
	string s1, s2, s;
	getline(cin, s1);
	getline(cin, s2);
	int n, min = -1;
	scanf("%d", &n);
	getchar();
	int a[n], f[n] = {0};
	for (int i = 0; i < n; ++i) {
		scanf("%d", &a[i]);
		getchar();
		getline(cin, s);
		if (s.find(' ') != string::npos) f[i] = 1;
		else {
			int c = 0, len = s.length();
			for (int j = 0; j < len; ++j)
				if (s[j] != '0') ++c;
			if (c != a[i]) f[i] = 1;
			else {
				string b = "";
				int l1 = 0;
				for (int j = 0; j < len; ++j) {
					if (s[j] == '0') {
						b.push_back(s1[l1++]);
					} else if (s[j] == '1') {
						++l1;
					} else if (s[j] == '2') {
						b.push_back(s2[b.length()]);
						++l1;
					} else if (s[j] == '3') {
						b.push_back(s2[b.length()]);
					}
				}
				if (b == s2) {
					if (min == -1) min = a[i];
					else if (a[i] < min) min = a[i];
					f[i] = 0;
				} else {
					f[i] = 1;
				}
			}
		}
	}
	for (int i = 0; i < n; ++i) {
		if (!f[i] && a[i] == min) printf("AC\n");
		else printf("WA\n");
	}
	return 0;
}

7-4 数组与链表  前缀和

坑点分析:    ""这种结构首先初始化一个长度为 L0​ 的整型数组 A0​,返回给用户使用。""

题目在一开始就告诉你了  先初始化了一个数字A0 代表无论访问合与不合法  最一开始就已经开了一个数组A0   所以在最后输出一共开了多少数组时候?  注意当全部访问为非法时候 , 一共开了1个数组就是最开始初始化的那个  所以不是0是1!!!!!!

#include<bits/stdc++.h>
using namespace std;
int main(void) {
	int n, k, t, max = 1;
	cin >> n >> k;
	int a[n] = {0}, b[n];
	for (int i = 0; i < n; ++i) {
		cin >> b[i] >> a[i];
		if (i == 0) --a[i];
		else a[i] += a[i - 1];
	}
	for (int i = 0; i < k; ++i) {
		cin >> t;
        if (t >a[n-1]) printf("Illegal Access\n");
        else {
		int len = 0;
		while (len < n && t > a[len])
			len++;
			if (len + 1 >= max) max = len + 1;
			if (len) t -= (a[len - 1] + 1);
			printf("%d\n", b[len] + t * sizeof(int));
		}
	}
	printf("%d", max);
	return 0;
}

7-5 取帽子 排序

当然这里我没用排序算法,我直接用的map容器 按key值从小到大存储

对帽子序列map存一个     对人序列map存一个  然后再遍历两个map容器建立对应关系

#include<bits/stdc++.h>
using namespace std;
int main(void) {
	int n, t;
	cin >> n;
	int a[n];
	map<int, int> m1, m2;
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
		m1[a[i]] = 1;
	}
	for (int i = 0; i < n; ++i) {
		cin >> t;
		m2[t] = i + 1;
	}
	auto a1 = m1.begin();
	auto a2 = m2.begin();
	for (; a1 != m1.end() && a2 != m2.end(); a1++, a2++)
		a1->second = a2->second;
	bool f = 1;
	for (int i = n - 1; i > -1; --i) {
		printf("%s%d", f ? "" : " ", m1[a[i]]);
		f = 0;
	}
	return 0;
}
  • 29
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值