PAT甲级题分类汇编——计算
本文为PAT甲级分类汇编系列文章。
计算类,指以数学运算为主或为背景的题。
题号 | 标题 | 分数 | 大意 |
1058 | A+B in Hogwarts | 20 | 特殊进制加法 |
1059 | Prime Factors | 25 | 分解素因数 |
1060 | Are They Equal | 25 | 一定精度下两数是否相等 |
1065 | A+B and C (64bit) | 20 | 大数加法与比较 |
1069 | The Black Hole of Numbers | 20 | 黑洞数 |
1073 | Scientific Notation | 20 | 科学计数法还原 |
1081 | Rational Sum | 20 | 有理数加法 |
1088 | Rational Arithmetic | 20 | 有理数运算 |
1096 | Consecutive Factors | 20 | 最长连续因数 |
1100 | Mars Numbers | 20 | 进制转换 |
这类题,普遍分数低,大多是20分。20分题放到乙级也没啥问题,比如1069、1081等。然而,即使是20分题,也可能要卡很久。
1059:
题目要求输出一个数的素因数分解。这么简单的题就不多讲了吧,直接上代码:
- #include <iostream>
- #include <map>
- #include <cmath>
- bool isprime(int n)
- {
- int end = std::sqrt(n) + ;
- for (int i = ; i != end; ++i)
- if (n % i == )
- return false;
- return true;
- }
- int main(int argc, char const *argv[])
- {
- long n;
- std::cin >> n;
- std::cout << n << '=';
- if (n == )
- {
- std::cout << '';
- return ;
- }
- std::map<int, int> factors;
- int prime = ;
- while (n > )
- {
- if (isprime(prime) && n % prime == )
- {
- ++factors[prime];
- n /= prime;
- }
- else
- ++prime;
- }
- int count = ;
- for (const auto& pair : factors)
- {
- if (count++)
- std::cout << '*';
- std::cout << pair.first;
- if (pair.second > )
- std::cout << '^' << pair.second;
- }
- return ;
- }
其实用 std::vector 也是可以的,但我懒。
需要注意的是 n== 的检查,不过这个很容易发现。
1065:
要求判断两个64位整数相加是否大于另一个数。注意两个64位整数相加以后如果还保存在64位整数中是可能溢出的,并且test case里面一定会有这种情况。
所以要用更大的整数来做计算。然而C++标准库中并没有提供128位整数。这时,伟大的g++出现了,它提供了 __int128_t :
- #include <iostream>
- int main(int argc, char const *argv[])
- {
- int t;
- std::cin >> t;
- std::cout << std::boolalpha;
- for (int i = ; i <= t; ++i)
- {
- __int128_t a, b, c;
- int64_t ta, tb, tc;
- std::cin >> ta >> tb >> tc;
- a = ta; b = tb; c = tc;
- std::cout << "Case #" << i << ": " << (a + b > c) << std::endl;
- }
- return ;
- }
于是这道题就被秒了。
C++标准库对整数类型的支持不太好,大整数的类只能自己写。至于是以二进制存储还是以十进制存储,那要看应用场景了。
1088:
在一个case上卡了好久,最后发现题目里有一句要用 long int ,WCNM。
难度没什么的,主要是对分子和分母有0或1的特殊情况的处理。
优雅的我写了一份很优雅的实现,又是template又是运算符重载的:
- #include <iostream>
- #include <exception>
- template <typename T>
- class Rational
- {
- public:
- Rational() = default;
- Rational(T _num, T _den)
- : numerator(_num), denominator(_den)
- {
- reduce();
- }
- Rational(const Rational&) = default;
- Rational& operator=(const Rational&) = default;
- Rational operator+(const Rational& _rhs) const noexcept
- {
- return Rational(numerator * _rhs.denominator + _rhs.numerator * denominator,
- denominator * _rhs.denominator);
- }
- Rational operator-(const Rational& _rhs) const noexcept
- {
- return Rational(numerator * _rhs.denominator - _rhs.numerator * denominator,
- denominator * _rhs.denominator);
- }
- Rational operator*(const Rational& _rhs) const noexcept
- {
- return Rational(numerator * _rhs.numerator,
- denominator * _rhs.denominator);
- }
- Rational operator/(const Rational& _rhs) const
- {
- if (_rhs.numerator == )
- throw std::exception();
- return Rational(numerator * _rhs.denominator,
- denominator * _rhs.numerator);
- }
- template <typename U>
- friend std::istream& operator>>(std::istream&, Rational<U>&);
- template <typename U>
- friend std::ostream& operator<<(std::ostream&, const Rational<U>&);
- private:
- static T gcd(T _lhs, T _rhs)
- {
- if (_lhs < )
- _lhs = -_lhs;
- if (_lhs < _rhs)
- return gcd(_rhs, _lhs);
- if (_rhs == )
- return _lhs ? _lhs : ;
- return gcd(_rhs, _lhs % _rhs);
- }
- void reduce()
- {
- if (denominator < )
- {
- numerator = -numerator;
- denominator = -denominator;
- }
- auto factor = gcd(numerator, denominator);
- numerator /= factor;
- denominator /= factor;
- }
- T numerator;
- T denominator;
- };
- template <typename T>
- std::istream& operator>>(std::istream& _is, Rational<T>& _r)
- {
- T n, d;
- std::cin >> n;
- std::cin.get();
- std::cin >> d;
- _r = Rational<T>(n, d);
- return _is;
- }
- template <typename T>
- std::ostream& operator<<(std::ostream& _os, const Rational<T>& _r)
- {
- auto r = _r;
- bool neg = false;
- if (r.numerator < )
- {
- neg = true;
- r.numerator = -r.numerator;
- _os << "(-";
- }
- if (r.denominator == )
- _os << r.numerator;
- else
- {
- if (r.numerator >= r.denominator)
- {
- _os << (r.numerator / r.denominator) << ' ';
- r.numerator %= r.denominator;
- }
- _os << r.numerator << '/' << r.denominator;
- }
- if (neg)
- _os << ')';
- return _os;
- }
- int main(int argc, char const *argv[])
- {
- Rational<long long> lhs, rhs;
- std::cin >> lhs >> rhs;
- std::cout << lhs << " + " << rhs << " = " << (lhs + rhs) << std::endl;
- std::cout << lhs << " - " << rhs << " = " << (lhs - rhs) << std::endl;
- std::cout << lhs << " * " << rhs << " = " << (lhs * rhs) << std::endl;
- std::cout << lhs << " / " << rhs << " = ";
- try
- {
- std::cout << (lhs / rhs) << std::endl;
- }
- catch(const std::exception& e)
- {
- std::cout << "Inf" << std::endl;
- }
- return ;
- }
优雅个屁,考试要来不及的。
顺便讲讲写自定义类(特指有成员方法的类而非简单的结构体)和模板的技巧。
构造函数最好给一个默认的,Rule of Three/Five规定的方法最好显式 =default 写出来。
参数尽量用引用,看情况要不要加 const ,大多都是要加的。相应地,成员方法能用 const 修饰的一定要加上去。
对于模板类的友元函数,模板类中还要再套模板,而且要用不一样的类型名称。
以上规则如果不遵守,很可能会编译错误,而且错误信息看起来比较累。
1096:
要求输出给定整数的的分解中可以出现的最长连续因数。乍一看有一点难,但稍微想一想就会发现,这串因数不会太长,因为阶乘是很大的。所以可以一个一个试这串因数中的最小数,连续很多个因数只有没几种情况需要试,到连续两个的情况,也是O(sqrt(n))时间复杂度能搞定的。至于单个因数则需要单独讨论一下,因为试到根号n就可以了,而如果不停止的话会超时。
- #include <iostream>
- #include <utility>
- #include <cmath>
- int main(int argc, char const *argv[])
- {
- int n;
- std::cin >> n;
- try
- {
- for (int count = ; count > ; --count)
- {
- for (int min = ; ; ++min)
- {
- long product = ;
- for (int factor = min; factor != min + count; ++factor)
- product *= factor;
- if (product > n)
- break;
- if (n % product == )
- throw std::pair<int, int>(count, min);
- }
- }
- int end = std::sqrt(n) + ;
- for (int factor = ; factor != end; ++factor)
- if (n % factor == )
- throw std::pair<int, int>(, factor);
- throw std::pair<int, int>(, n);
- }
- catch(const std::pair<int, int>& pair)
- {
- std::cout << pair.first << std::endl;
- for (int i = pair.second; i != pair.second + pair.first - ; ++i)
- std::cout << i << '*';
- std::cout << pair.second + pair.first - << std::endl;
- }
- return ;
- }
长度的初始值是11,是因为2*3*...*13是大于2^31的,而2*3*...*12是小于2^31的,因此长度不会超过11。
总之,计算类题目没有难度,但是要避坑。坑依然是边界条件,包括最小的数(0、1、2等)与很大的数(int放不下的)。
PAT甲级题分类汇编——计算的更多相关文章
- PAT甲级题分类汇编——杂项
本文为PAT甲级分类汇编系列文章. 集合.散列.数学.算法,这几类的题目都比较少,放到一起讲. 题号 标题 分数 大意 类型 1063 Set Similarity 25 集合相似度 集合 1067 ...
- PAT甲级题分类汇编——图
本文为PAT甲级分类汇编系列文章. 图,就是层序遍历和Dijkstra这一套,#include<queue> 是必须的. 题号 标题 分数 大意 时间 1072 Gas Station 3 ...
- PAT甲级题分类汇编——树
本文为PAT甲级分类汇编系列文章. AVL树好难!(其实还好啦~) 我本来想着今天应该做不完树了,没想到电脑里有一份讲义,PPT和源代码都有,就一遍复习一遍抄码了一遍,更没想到的是编译一遍通过,再没想 ...
- PAT甲级题分类汇编——理论
本文为PAT甲级分类汇编系列文章. 理论这一类,是让我觉得特别尴尬的题,纯粹是为了考数据结构而考数据结构.看那Author一栏清一色的某老师,就知道教数据结构的老师的思路就是和别人不一样. 题号 标题 ...
- PAT甲级题分类汇编——排序
本文为PAT甲级分类汇编系列文章. 排序题,就是以排序算法为主的题.纯排序,用 std::sort 就能解决的那种,20分都算不上,只能放在乙级,甲级的排序题要么是排序的规则复杂,要么是排完序还要做点 ...
- PAT甲级题分类汇编——线性
本文为PAT甲级分类汇编系列文章. 线性类,指线性时间复杂度可以完成的题.在1051到1100中,有7道: 题号 标题 分数 大意 时间 1054 The Dominant Color 20 寻找出现 ...
- PAT甲级题分类汇编——序言
今天开个坑,分类整理PAT甲级题目(https://pintia.cn/problem-sets/994805342720868352/problems/type/7)中1051~1100部分.语言是 ...
- 【转载】【PAT】PAT甲级题型分类整理
最短路径 Emergency (25)-PAT甲级真题(Dijkstra算法) Public Bike Management (30)-PAT甲级真题(Dijkstra + DFS) Travel P ...
- PAT甲级题解分类byZlc
专题一 字符串处理 A1001 Format(20) #include<cstdio> int main () { ]; int a,b,sum; scanf ("%d %d& ...
随机推荐
- [教程] Packt - Create a Game Environment with Blender and Unity by Darrin Lile
学习了解如何使用Blender,photoshop和Unity创建自己的游戏环境!了解如何通过比以往更加集成的方式使用Blender和Unity,将自己的游戏设计变为现实.在Unity中创建测试版本 ...
- Grafana 在添加邮件和钉钉报警之后不报警的原因是没有重启grafana 不生效重启。
即使在grafana页面上面添加也需要重启.配置邮件配置文件更需要重启. systemctl restart grafana-server.service
- mysql起容器的最精简命令
亲测有效的 mysql 容器命令: #pull mysql:5.6 docker pull mysql:5.6 #起容器,映射3306端口,配置root用户密码 docker run -di --na ...
- flutter 不规则底部工具栏实现
import 'package:flutter/material.dart'; import 'each_view.dart'; class BottomAppBarDemo extends Stat ...
- Ionic app IOS 在Xcode 模拟运行 真机调试
1. 创建项目: sudo ionic start myApp tabs 2 cd 到刚才创建的项目 3. sudo ionic cordova platform add ios 把 ios 环境添加 ...
- 详解Django rest_framework实现RESTful API
这篇文章主要介绍了详解Django rest_framework实现RESTful API,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 一.什么是REST 面向资源是R ...
- jenkins发布程序触发shell调用python脚本刷新akamai cdn api
刷新cdn的流程:jenkins获取git中的代码,触发脚本推送到生产环境中(即cdn的源站) --> 触发脚本获取git工作目录的更新列表,将更新列表拼凑成带域名信息的url,写入到目录中 - ...
- 【转载】 谷歌集群数据分析 clusterdata-2011-2
原文地址: https://www.twblogs.net/a/5c2dc304bd9eee35b21c418b/zh-cn ------------------------------------- ...
- ROS Software update
http://packages.ros.org/ros/ubuntu
- Java中使用Socket连接判断Inputstream结束,java tcp socket服务端,python tcp socket客户端
最近在试着用java写一个socket的服务器,用python写一个socket的客户端来完成二者之间的通信,但是发现存在一个问题,服务器方面就卡在读取inputsream的地方不动了,导致后面的代码 ...