PAT甲级刷题记录-(AcWing)-(Day03高精度与进位制 8题)
课程来源AcWing 其中AcWing中的题目为翻译好的中文题目
今日刷题列表
- 1002 A+B for Polynomials
- 1009 Product of Polynomials
- 1023 Have Fun with Numbers
- 1024 Palindromic Number
- 1010 Radix
- 1015 Reversible Primes
- 1027 Colors in Mars
- 1100 Mars Numbers
1002 A+B for Polynomials
AcWing链接 PAT链接
英语单词
- polynomials 多项式
- nonzero terms 非零项
- exponents and coefficients 指数和系数
解析
- 使用三个
double 数组来存放多项式的系数 - 数组的下标代表了多项式的次数
- 通过遍历将
a 与b 多项式的和累加到c 上
注意点
con 的判断过程中,要注意到类似a = [1 ... ] ,b =[ -1 ... ] 的情况, 也就是说在a ,与b 中存在该次数的系数,但是累加之后被消去,不能统计到con 中- 如果最后的结果是
0 , 单单输出0 即可 - 输出控制保留一位小数
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <sstream>
const int N = 1010;
using namespace std;
double a[N], b[N], c[N];
int main() {
int k;
cin >> k;
int exponent;
for (int i = 0; i < k; ++i) {
cin >> exponent;
cin >> a[exponent];
}
cin >> k;
for (int i = 0; i < k; ++i) {
cin >> exponent;
cin >> b[exponent];
}
int con = 0;
for (int i = 0; i < N; ++i) {
if (a[i] || b[i]) {
c[i] += a[i] + b[i];
if(c[i])
con++;
}
}
cout << con;
for (int i = N - 1; i >= 0; i--) {
if (c[i]) {
printf(" %d %.1f", i, c[i]);
}
}
return 0;
}
1009 Product of Polynomials
AcWing链接 PAT链接
英语单词
- Product 乘积
解析 - 存储方面与上一题类似, 主要区别在于计算多项式的乘法
- 对于多项式的乘法可以采取两层循环,即让多项式
a 的每一项与多项式b 来相乘, 相乘的过程为c[i + j] += a[i] * b[j]; 也就是系数相乘, 指数相加- 后面的操作与上一题一模一样
#include <iostream>
#include <cstdio>
const int N = 1010;
using namespace std;
double a[N], b[N], c[2 * N];
int main() {
int k;
cin >> k;
int exponent;
while (k--) {
cin >> exponent;
cin >> a[exponent];
}
cin >> k;
while (k--) {
cin >> exponent;
cin >> b[exponent];
}
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (a[i] || b[j]) {
c[i + j] += a[i] * b[j];
}
}
}
int con = 0;
for (int i = 0; i < 2 * N; ++i) {
if (c[i]) {
con++;
}
}
printf("%d", con);
for (int i = 2 * N - 1; i >= 0; i--) {
if (c[i]) {
printf(" %d %.1lf", i, c[i]);
}
}
return 0;
}
1023 Have Fun with Numbers
AcWing链接 PAT链接
英语单词
- consisting 组成
- permutation 排列
- this property 这个性质
解析 long long形的整数大概是18位左右,而题目中的要求是no more than 20 digits , 因此这里用数组或者vector 来存取 知识点
tips: c++中的sort函数
- 可以直接用
== 来比较两个vector 数组是否相等 sort 排序的用法
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> double_number(vector<int> &a) {
vector<int> b;
int t = 0, i;
for (i = a.size() - 1; i >= 0; i--) {
b.push_back((a[i] * 2 + t) % 10);
t = (a[i] * 2 + t) / 10;
}
if (t)
b.push_back(t);
return b;
}
int main() {
string n;
cin >> n;
vector<int> number;
for (int i = 0; i < n.size(); ++i) {
number.push_back(n[i] - '0');
}
vector<int> result = double_number(number);
vector<int> tmp = result;
sort(number.begin(), number.end());
sort(tmp.begin(), tmp.end());
if (tmp == number) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
for (int i = result.size() - 1; i >= 0; i--) {
cout << result[i];
}
return 0;
}
1024 Palindromic Number
AcWing链接 PAT链接
英语单词
- Palindromic Number 回文数
- via 经过,通过
解析
tips: vector反转
vector<int> b(a.rbegin(), a.rend())
tips: 两数相加通用模板
a 没循环完就继续加a b 没循环完就继续加b 进位t 还在就继续加t
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
bool is_data(vector<int> &x) {
for (int i = 0, j = x.size() - 1; i < j; ++i, --j) {
if (x[i] != x[j]) return false;
}
return true;
}
vector<int> add_vec(vector<int> &a) {
vector<int> b, c;
int t = 0, i;
for (i = a.size() - 1; i >= 0; i--) {
b.push_back(a[i]);
}
for (i = 0; i < a.size(); ++i) {
c.push_back((a[i] + b[i] + t) % 10);
t = (a[i] + b[i] + t) / 10;
}
if (t)
c.push_back(t);
return c;
}
int main() {
string N;
int K;
cin >> N >> K;
vector<int> number;
int cur_k = 0;
for (int i = 0; i < N.size(); ++i) {
number.push_back(N[i] - '0');
}
if (is_data(number)) {
for (auto num:number) {
cout << num;
}
cout << endl << cur_k;
} else {
while (!is_data(number)) {
cur_k++;
number = add_vec(number);
if (cur_k == K)
break;
}
for (int i = number.size() - 1; i >= 0; --i) {
cout << number[i];
}
cout << endl << cur_k;
}
return 0;
}
1010 Radix
AcWing链接 PAT链接
英语单词
题解
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <sstream>
typedef long long LL;
using namespace std;
int get(char c) {
if (c <= '9') return c - '0';
else return c - 'a' + 10;
}
LL cal(string N1, LL radix) {
LL res = 0;
for (auto c:N1) {
if ((double) res * radix + get(c) > 1e16) return 1e18;
res = res * radix + get(c);
}
return res;
}
int main() {
string N1, N2;
int tag, radix;
cin >> N1 >> N2 >> tag >> radix;
if (tag == 2) {
swap(N1, N2);
}
LL target = cal(N1, radix);
LL l = 0;
for (auto c : N2) l = max(l, (LL) get(c) + 1);
LL r = target + 1;
while (l < r) {
LL mid = l + r >> 1;
if (cal(N2, mid) >= target) r = mid;
else l = mid + 1;
}
if (cal(N2, r) != target) puts("Impossible");
else cout << r << endl;
return 0;
}
1015 Reversible Primes
AcWing链接 PAT链接
英语单词
解析
- 注意反转数字的时候要先转成对应的进制反转,我一开始没想清楚直接用十进制反转了就G了
- 在翻转数字的过程中可以直接求得翻转后的十进制结果
- 比如
6 转为2 进制本该为110 ,翻转后得到011 - 而使用辗转相除法得到的二进制结果正是
011 , 可以直接使用res = res * 2 + n % d 的方式求和
#include <sstream>
#include <iostream>
#include <cstdio>
#include <algorithm>
typedef long long LL;
using namespace std;
bool is_prime(int x) {
if (x == 1) return false;
for (int i = 2; i * i <= x; ++i) {
if (x % i == 0)return false;
}
return true;
}
bool check(int n, int d) {
if (!is_prime(n)) return false;
int res = 0;
while (n) {
res = res * d + n % d;
n = n / d;
}
return is_prime(res);
}
int main() {
int n,d;
while (true) {
cin >> n;
if (n < 0)
break;
cin >> d;
if (check(n, d)) puts("Yes");
else puts("No");
}
return 0;
}
1027 Colors in Mars
AcWing链接 PAT链接
解析 本题思路很简单, 输入的三个数字, 把每个数字都转成相应的13进制就可以了 这里要注意到进制之间的转换问题,以及不满两位的补0问题 我的代码
#include <iostream>
#include <cstdio>
using namespace std;
void change(int r) {
if (r < 10)
printf("%02d", r);
else if (r < 13)
printf("0%c", r - 10 + 'A');
else {
int high = r / 13;
int low = r % 13;
if (high >= 10 && low >= 10)
printf("%c%c", high - 10 + 'A', low - 10 + 'A');
else if (high >= 10)
printf("%c%d", high - 10 + 'A', low);
else if (low >= 10)
printf("%d%c", high, low - 10 + 'A');
else
printf("%d%d", high, low);
}
}
int main() {
int r, g, b;
scanf("%d %d %d", &r, &g, &b);
printf("#");
change(r);
change(g);
change(b);
return 0;
}
优雅的代码
cout << get(a[i] / 13) << get(a[i] % 13); - 如果只有一位的情况下
a[i] / 13 其实是等于0的,只要这边输出0就好了,我没想到这一点
#include <iostream>
using namespace std;
char get(int x) {
if (x <= 9) return '0' + x;
return 'A' + x - 10;
}
int main() {
int a[3];
for (int i = 0; i < 3; ++i)cin >> a[i];
cout << '#';
for (int i = 0; i < 3; ++i) {
cout << get(a[i] / 13) << get(a[i] % 13);
}
return 0;
}
1100 Mars Numbers
AcWing链接 PAT链接
英语单词
- mutual translation 相互转换
- either or 要么 要么
- corresponding 相应的 相关的 对应的
解析 做这道题的时候碰到了很多小坑
- 用getline 获取一行,然后整行进行解析
- 如果带有数字, 那么将数字转换为火星数字
- 如果 是字符串 那么将字符串转换为整型数字
- 由于火星文只有两位所以数字转火星数字,只要将数字除以13和数字
mod 13进行操作 - 字符串需要对一位和两位的情况进行讨论
tips: stringstream的用处
C++ stringstream之妙用 stringstream用法 本题中使用stringstream ssin(data); 获取输入的string 类型地球字/火星字 自动根据空格分割他们并输出到指定的类型num2(string) 中 或转换为int 形变量num 我的答案
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <sstream>
using namespace std;
string a[13] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string b[12] = {"tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
int get_num(string num) {
for (int i = 0; i < 13; ++i) {
if (a[i] == num) return i;
}
for (int i = 0; i < 12; ++i) {
if (b[i] == num) return (i + 1) * 13;
}
}
int main() {
int n;
cin >> n;
getchar();
for (int i = 0; i < n; ++i) {
string data;
getline(cin, data);
stringstream ssin(data);
if (data[0] <= '9') {
int num;
ssin >> num;
if (num < 13) {
cout << a[num] << endl;
} else {
cout << b[num / 13 - 1];
if (num % 13 != 0)
cout << " " << a[num % 13];
cout << endl;
}
} else {
string num2;
int res = 0;
while (ssin >> num2) {
res += get_num(num2);
}
cout << res << endl;
}
}
return 0;
}
AcWing课程的答案
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <sstream>
using namespace std;
char names[][5] = {
"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec",
"tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"
};
int get(string word) {
for (int i = 0; i < 25; ++i) {
if (names[i] == word) {
if (i < 13) return i;
return ((i + 1) % 13) * 13;
}
}
}
int main() {
int n;
cin >> n;
getchar();
while (n--) {
string line;
getline(cin, line);
stringstream ssin(line);
if (line[0] <= '9') {
int v;
ssin >> v;
if (v < 13) cout << names[v] << endl;
else {
cout << names[12 + v / 13];
if (v % 13 == 0) cout << endl;
else cout << " " << names[v % 13] << endl;
}
} else {
int res = 0;
string word;
while (ssin >> word) res += get(word);
cout << res << endl;
}
}
return 0;
}
|