这个是我们学校自己拉的题,打一次天梯的模拟,看一下与三月底的天梯相比大家进步如何。所以我会把题目也放上,OK~
Here we go ~
7-1 N个数求和(20 分)
本题的要求很简单,就是求N
个数字的和。麻烦的是,这些数字是以有理数分子/分母
的形式给出的,你输出的和也必须是有理数的形式。
输入格式:
输入第一行给出一个正整数N
(≤100)。随后一行按格式a1/b1 a2/b2 ...
给出N
个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分
,其中分数部分写成分子/分母
,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
输入样例1:
5
2/5 4/15 1/30 -2/60 8/3
输出样例1:
3 1/3
输入样例2:
2
4/3 2/3
输出样例2:
2
输入样例3:
3
1/3 -1/6 1/8
输出样例3:
7/24
思路:
求分母最小公倍数,记为mul,然后对应的分子也相应变换,再对分子求和记为sum, 这样整数部分就是 ans = sum / mul, 如果ans != 0 , 就输出,记一个tmp = sum % mul ,若 tmp == 0,那就只输出整数部分ans, 若都不为0 ,约个分就OK啦~
本人AC代码:
#include <cstdio>#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
int n;
char c;
ll a[105];
ll b[105];
ll Gcd(ll x, ll y) {
if(x % y == 0) return y;
else return Gcd(y, x % y);
}
ll Lcm(ll x, ll y) {return x * y / Gcd(x, y);}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lld%c%lld", &a[i], &c, &b[i]);
ll mul = b[1];
for(int i = 2; i <= n; i++) mul = Lcm(mul, b[i]);
for(int i = 1; i <= n; i++) a[i] *= (mul / b[i]);
ll sum = 0;
for(int i = 1; i <= n; i++) sum += a[i];
ll ans = sum / mul;
ll res = sum - ans * mul;
ll tmp = sum % mul;
if(tmp == 0) {
printf("%d\n", ans);
return 0;
}
if(ans) printf("%lld ", ans);
printf("%lld/%lld\n", res / Gcd(res, mul), mul / Gcd(res, mul));
}
7-2 比较大小(10 分)
本题要求将输入的任意3个整数从小到大输出。
输入格式:
输入在一行中给出3个整数,其间以空格分隔。
输出格式:
在一行中将3个整数从小到大输出,其间以“->”相连。
输入样例:
4 2 8
输出样例:
2->4->8
思路:直接sort排序。
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int a[5];
int main() {
for(int i = 1; i <= 3; i++) scanf("%d", &a[i]);
sort(a + 1, a + 4);
printf("%d->%d->%d\n", a[1], a[2], a[3]);
}
7-3 A-B(20 分)
本题要求你计算A−B。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A−B。
输入格式:
输入在2行中先后给出字符串A和B。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。
输出格式:
在一行中打印出A−B的结果字符串。
输入样例:
I love GPLT! It's a fun game!
aeiou
输出样例:
I lv GPLT! It's fn gm!
思路:
直接对第二个串的字符标记,在第一个串内如果碰到被标记的字符就跳过,反之输出,gets( )读入,空格需要单独特判。
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int Maxx = 1e4 + 7;
char s[Maxx];
char t[Maxx];
bool vis[Maxx];
int main() {
gets(s);
gets(t);
int ls = strlen(s);
int lt = strlen(t);
for(int i = 0; i < lt; i++) vis[t[i]] = 1;
for(int i = 0; i < ls; i++) {
if(s[i] == ' ' && !vis[s[i]]) printf(" ");
else {
if(!vis[s[i]]) printf("%c", s[i]);
}
}
printf("\n");
}
7-4 计算指数(5 分)
真的没骗你,这道才是简单题 —— 对任意给定的不超过10的正整数n,要求你输出2n。不难吧?
输入格式:
输入在一行中给出一个不超过10的正整数n。
输出格式:
在一行中按照格式 2^n = 计算结果
输出2n的值。
输入样例:
5
输出样例:
2^5 = 32
思路:根据题意暴力即可。
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n;
int main() {
scanf("%d", &n);
int ans = 1;
for(int i = 1; i <= n; i++) ans *= 2;
printf("2^%d = %d\n", n, ans);
}
7-5 计算阶乘和(10 分)
对于给定的正整数N,需要你计算 S=1!+2!+3!+...+N!。
输入格式:
输入在一行中给出一个不超过10的正整数N。
输出格式:
在一行中输出S的值。
输入样例:
3
输出样例:
9
思路:数据不大,直接暴力。
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n;
int main() {
scanf("%d", &n);
int sum = 0;
for(int i = 1; i <= n; i++) {
int ans = 1;
for(int j = 1; j <= i; j++) ans *= j;
sum += ans;
}
printf("%d\n", sum);
}
7-6 简单题(5 分)
这次真的没骗你 —— 这道超级简单的题目没有任何输入。
你只需要在一行中输出事实:This is a simple problem.
就可以了。
思路:送人头的题
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int main() {
puts("This is a simple problem.");
}
7-7 跟奥巴马一起画方块(15 分)
美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!
输入格式:
输入在一行中给出正方形边长N(3≤N≤21)和组成正方形边的某种字符C
,间隔一个空格。
输出格式:
输出由给定字符C
画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的50%(四舍五入取整)。
输入样例:
10 a
输出样例:
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
思路:奇数的行数就加1再除二,偶数就直接除2.
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n;
char c;
int t;
int main() {
scanf("%d %c", &n, &c);
if(n & 1) t = (n + 1) / 2;
else t = n / 2;
for(int i = 1; i <= t; i++) {
for(int j = 1; j <= n; j++) printf("%c", c);
printf("\n");
}
}
7-8 查验身份证(15 分)
一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:
首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值Z
;最后按照以下关系对应Z
值与校验码M
的值:
Z:0 1 2 3 4 5 6 7 8 9 10
M:1 0 X 9 8 7 6 5 4 3 2
现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。
输入格式:
输入第一行给出正整数N(≤100)是输入的身份证号码的个数。随后N行,每行给出1个18位身份证号码。
输出格式:
按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理,只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常,则输出All passed
。
输入样例1:
4
320124198808240056
12010X198901011234
110108196711301866
37070419881216001X
输出样例1:
12010X198901011234
110108196711301866
37070419881216001X
输入样例2:
2
320124198808240056
110108196711301862
输出样例2:
All passed
思路:根据题意模拟即可,注意最后一位校验码,先加权再模11.
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
char s[105][25];
bool flg[105];
int p[25];
int t[20] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%s", s[i]);
for(int i = 1; i <= n; i++) flg[i] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 0; j < 17; j++) {
if(s[i][j] < '0' || s[i][j] > '9') flg[i] = 0;
}
}
int sum;
for(int i = 1; i <= n; i++) {
if(flg[i]) {
sum = 0;
for(int j = 0; j < 17; j++) {
if(s[i][j] == '0') p[j] = 0;
else if(s[i][j] == '1') p[j] = 1;
else if(s[i][j] == '2') p[j] = 2;
else if(s[i][j] == '3') p[j] = 3;
else if(s[i][j] == '4') p[j] = 4;
else if(s[i][j] == '5') p[j] = 5;
else if(s[i][j] == '6') p[j] = 6;
else if(s[i][j] == '7') p[j] = 7;
else if(s[i][j] == '8') p[j] = 8;
else if(s[i][j] == '9') p[j] = 9;
sum += p[j] * t[j];
}
if(sum % 11 == 0) {
if(s[i][17] == '1') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 1) {
if(s[i][17] == '0') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 2) {
if(s[i][17] == 'X') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 3) {
if(s[i][17] == '9') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 4) {
if(s[i][17] == '8') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 5) {
if(s[i][17] == '7') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 6) {
if(s[i][17] == '6') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 7) {
if(s[i][17] == '5') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 8) {
if(s[i][17] == '4') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 9) {
if(s[i][17] == '3') flg[i] = 1;
else flg[i] = 0;
}
else if(sum % 11 == 10) {
if(s[i][17] == '2') flg[i] = 1;
else flg[i] = 0;
}
}
}
int cnt = 0;
for(int i = 1; i <= n; i++) {
if(flg[i]) cnt++;
}
if(cnt == n) {
puts("All passed");
return 0;
}
for(int i = 1; i <= n; i++) {
if(!flg[i]) puts(s[i]);
}
}
7-12 最长对称子串(25 分)
对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定Is PAT&TAP symmetric?
,最长对称子串为s PAT&TAP s
,于是你应该输出11。
输入格式:
输入在一行中给出长度不超过1000的非空字符串。
输出格式:
在一行中输出最长对称子串的长度。
输入样例:
Is PAT&TAP symmetric?
输出样例:
11
思路:假DP,真暴力,对每个位置开始枚举,如果该位置与它前一个位置相等,那就从它前一个位置向左扫,从该位置向右扫;若不等,那就直接从该位置向两边扫,用max维护即可。
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int Maxx = 1e3 + 7;
char s[Maxx];
int cnt;
int main() {
gets(s);
//puts("1000");
int max = -10000000;
int l = strlen(s);
for(int i = 0; i < l; i++) {
int j = 1;
if(s[i] != s[i - 1]) {
cnt = 1;
while(s[i - j] == s[i + j] && i - j >= 0) {
j++;
cnt += 2;
}
}
else {
int p1 = i, p2 = i - 1;
cnt = 2;
while(s[p2 - j] == s[p1 + j] && p2 - j >= 0) {
j++;
cnt += 2;
}
}
if(cnt > max) max = cnt;
}
printf("%d\n", max);
}
7-14
骗了2分,因为题意说若不满足某种情况就输出
No Solution
所以我就可耻的写好输入格式就直接puts("No Solution");
骗了两分,正好我第一阶段差两分就AK了,所以正好补回来,相当于我第一阶段AK了,第二阶段AC了一道25分的题,最开始一共砍下来125分,7-1的20分没有得满,只拿了18分,因为当时突然不会写最小公倍数了。。。就记了一个累乘的值冒充了一下最小公倍数,果然失精了,赛后补过了,现在的7-1是AC代码,话说求两数最小公倍数,只需要求他俩乘积再除以最大公约数即可。相比三月底惨不忍睹的62分,还是狠狠地翻了一番的~