SWUN 天梯赛模拟赛 部分题解

这个是我们学校自己拉的题,打一次天梯的模拟,看一下与三月底的天梯相比大家进步如何。所以我会把题目也放上,OK~

Here we go ~

7-1 N个数求和(20 分)

本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。

输入格式:

输入第一行给出一个正整数N100)。随后一行按格式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 分)

本题要求你计算AB。不过麻烦的是,AB都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串AB

输入格式:

输入在2行中先后给出字符串AB。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。

输出格式:

在一行中打印出AB的结果字符串。

输入样例:

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年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!

输入格式:

输入在一行中给出正方形边长N3N21)和组成正方形边的某种字符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

现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。

输入格式:

输入第一行给出正整数N100)是输入的身份证号码的个数。随后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分,还是狠狠地翻了一番的~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值