在这次考试我乙级得到了95分,分享题目和解法望大家指出错误!
7-1 B是A的多少倍 (15 分)
设一个数 A 的最低 D 位形成的数是 ad。如果把 ad截下来移到 A 的最高位前面,就形成了一个新的数 B。B 是 A 的多少倍?例如将 12345 的最低 2 位 45 截下来放到 123 的前面,就得到 45123,它约是 12345 的 3.66 倍。
输入格式:
输入在一行中给出一个正整数 A(≤10^9)和要截取的位数 D。题目保证 D 不超过 A 的总位数。
输出格式:
计算 B 是 A 的多少倍,输出小数点后 2 位。
输入样例 1:
12345 2
输出样例 1:
3.66
输入样例 2:
12345 5
输出样例 2:
1.00
#include<iostream>
using namespace std;
int main() {
string s;
int n;
cin >> s >> n;
string ans = s.substr(s.length() - n, n) + s.substr(0, s.length() - n);
long long a = stoi(ans), b = stoi(s);
printf("%.2f", a * 1.0 / b);
return 0;
}
7-2 教超冠军卷 (20 分)
“教育超市”是拼题 A 系统的一个衍生产品,发布了各种试卷和练习供用户选购。在试卷列表中,系统不仅列出了每份试卷的单价,还显示了当前的购买人次。本题就请你根据这些信息找出教育超市所有试卷中的销量(即购买人次)冠军和销售额冠军。
输入格式:
输入首先在第一行中给出一个正整数 N(≤10^4 ),随后 N 行,每行给出一份卷子的独特 ID (由小写字母和数字组成的、长度不超过8位的字符串)、单价(为不超过 100 的正整数)和购买人次(为不超过10^6的非负整数)。
输出格式:
在第一行中输出销量冠军的 ID 及其销量,第二行中输出销售额冠军的 ID 及其销售额。同行输出间以一个空格分隔。题目保证冠军是唯一的,不存在并列。
输入样例:
4
zju007 39 10
pku2019 9 332
pat2018 95 79
qdu106 19 38
输出样例:
pku2019 332
pat2018 7505
#include<iostream>
using namespace std;
struct node {
string code;
int s, p;
};
int main() {
long long n, m1 = 0, m2 = 0;
cin >> n;
vector<node> v(n);
for(int i = 0; i < n; i++) {
cin >> v[i].code >> v[i].s >> v[i].p;
if(v[m1].p < v[i].p) {
m1 = i;
}
if(v[m2].s * v[m2].p < v[i].s * v[i].p) {
m2 = i;
}
}
cout << v[m1].code << " " << v[m1].p << endl;
cout << v[m2].code << " " << v[m2].s * v[m2].p;
return 0;
}
7-3 缘分数 (20 分)
所谓缘分数是指这样一对正整数 a 和 b,其中 a 和它的小弟 a−1 的立方差正好是另一个整数 c 的平方,而 c 正好是 b 和它的小弟 b−1 的平方和。例如 8^3 − 7^3 = 169 = 13^2 ,而 13 = 3^2 + 2^2,于是 8 和 3 就是一对缘分数。
给定 a 所在的区间 [m,n],是否存在缘分数?
输入格式:
输入给出区间的两个端点 0 < m < n ≤ 25000,其间以空格分隔。
输出格式:
按照 a 从小到大的顺序,每行输出一对缘分数,数字间以空格分隔。如果无解,则输出 No Solution。
输入样例 1:
8 200
输出样例 1:
8 3
105 10
输入样例 2:
9 100
输出样例 2:
No Solution
#include<iostream>
#include<cmath>
using namespace std;
int main() {
long long m, n;
int flag = 0;
cin >> m >> n;
for(long long i = m; i <= n; i++) {
long long c2 = abs(i * i * i - (i - 1) * (i - 1) * (i - 1));
for(int j = 2; j <= sqrt(n); j++) { //根号是为了防止超时,赌了一把
if(sqrt(c2) == j * j + (j - 1) * (j - 1)) {
if(flag) cout << endl;
cout << i << " " << j;
flag = 1;
break;
}
}
}
if(!flag) cout << "No Solution";
return 0;
}
7-4 天长地久 (20 分)(一超时)
“天长地久数”是指一个 K 位正整数 A,其满足条件为:A 的各位数字之和为 m,A+1 的各位数字之和为 n,且 m 与 n 的最大公约数是一个大于 2 的素数。本题就请你找出这些天长地久数。
输入格式:
输入在第一行给出正整数 N(≤5),随后 N 行,每行给出一对 K(3<K<10)和 m(1<m<90),其含义如题面所述。
输出格式:
对每一对输入的 K 和 m,首先在一行中输出 Case X,其中 X 是输出的编号(从 1 开始);然后一行输出对应的 n 和 A,数字间以空格分隔。如果解不唯一,则每组解占一行,按 n 的递增序输出;若仍不唯一,则按 A 的递增序输出。若解不存在,则在一行中输出 No Solution。
输入样例:
2
6 45
7 80
输出样例:
Case 1
10 189999
10 279999
10 369999
10 459999
10 549999
10 639999
10 729999
10 819999
10 909999
Case 2
No Solution
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int gcd(long a, long b) {
return b == 0 ? a : gcd(b, a % b);
}
struct node {
int a, b;
};
int cmp(node a, node b) {
if(a.a != b.a) return a.a < b.a;
else return a.b < b.b;
}
bool isprime(long a) {
if(a <= 2) return false;
for(int i = 3; i * i < a; i += 2) {
if(a % i == 0) return false;
}
return true;
}
int getsum(int num) {
int sum = 0;
while(num) {
sum += num % 10;
num /= 10;
}
return sum;
}
int main() {
int n;
cin >> n;
for(int i = 1; i <= n; i++) {
int a, b;
vector<node> v;
cin >> a >> b;
cout << "Case " << i << endl;
long num = 1;
for(int j = 1; j < a; j++) num *= 10;
long e = num * 10;
for(long j = num; j < e; j++) {
int c = getsum(j), d = getsum(j + 1);
if(c == b && isprime(gcd(c, d))) {
v.push_back( node{ d, j } );
}
}
if(v.size() == 0) cout << "No Solution" << endl;
else {
sort(v.begin(), v.end(), cmp);
for(int i = 0; i < v.size(); i++) {
cout << v[i].a << " " << v[i].b << endl;
}
}
}
return 0;
}
7-5 链表合并 (25 分)
给定两个单链表 L1 = a1→a2→⋯→an−1→an 和 L2 = b1→b2→⋯→bm−1→bm 。如果 n≥2m,你的任务是将比较短的那个链表逆序,然后将之并入比较长的那个链表,得到一个形如 a1→a2→bm→a3→a4→bm−1 ⋯ 的结果。例如给定两个链表分别为 6→7 和 1→2→3→4→5,你应该输出 1→2→7→3→4→6→5。
输入格式:
输入首先在第一行中给出两个链表 L1和 L2的头结点的地址,以及正整数 N (≤10^5),即给定的结点总数。一个结点的地址是一个 5 位数的非负整数,空地址 NULL 用 -1 表示。
随后 N 行,每行按以下格式给出一个结点的信息:
Address Data Next
其中 Address
是结点的地址,Data
是不超过 10
5的正整数,Next
是下一个结点的地址。题目保证没有空链表,并且较长的链表至少是较短链表的两倍长。
输出格式:
按顺序输出结果链表,每个结点占一行,格式与输入相同。
输入样例:
00100 01000 7
02233 2 34891
00100 6 00001
34891 3 10086
01000 1 02233
00033 5 -1
10086 4 00033
00001 7 -1
输出样例:
01000 1 02233
02233 2 00001
00001 7 34891
34891 3 10086
10086 4 00100
00100 6 00033
00033 5 -1
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector<int> d(100000), n(100000), l1(100000), l2(100000);
int h1, h2, m, t, len1 = 0, len2 = 0;
cin >> h1 >> h2 >> m;
for(int i = 0; i < m; i++) {
cin >> t;
cin >> d[t] >> n[t];
}
while(h1 != -1) {
l1[len1++] = h1;
h1 = n[h1];
}
while(h2 != -1) {
l2[len2++] = h2;
h2 = n[h2];
}
int flag = 0;
if(len1 >= len2 * 2) {
for(int i = 0; i < len1; i++) {
if(flag == 0) {
printf("%05d %d ", l1[i], d[l1[i]]);
flag = 1;
} else {
printf("%05d\n%05d %d ", l1[i], l1[i], d[l1[i]]);
if(i % 2 == 1 && len2 > 0) {
len2--;
printf("%05d\n%05d %d ", l2[len2], l2[len2], d[l2[len2]]);
}
}
}
cout << -1;
} else {
for(int i = 0; i < len2; i++) {
if(flag == 0) {
printf("%05d %d ", l2[i], d[l2[i]]);
flag = 1;
} else {
printf("%05d\n%05d %d ", l2[i], l2[i], d[l2[i]]);
if(i % 2 == 1 && len1 > 0) {
len1--;
printf("%05d\n%05d %d ", l1[len1], l1[len1], d[l1[len1]]);
}
}
}
cout << -1;
}
return 0;
}
第一次写博客,望大家包含,考场上也太紧张,没想到加上c99的编译语法,希望大家多多支持哈!
并且在第四题有个测试点超时了,也看看大家能不能给些什么建议优化一下!