csu-2018年11月月赛Round2-div2题解

Posted artoriax

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csu-2018年11月月赛Round2-div2题解相关的知识,希望对你有一定的参考价值。

csu-2018年11月月赛Round2-div2题解

A(2193):昆虫繁殖

Description

科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。每对成虫过x个月产y对卵,每对卵要过两个月长成成虫。假设每个成虫不死,第一个月只有一对成虫,且卵长成成虫后的第一个月不产卵(过X个月产卵),问过Z个月以后,共有成虫多少对?0=<X<=20,1<=Y<=20,X=<Z<=50

Input

单组数据 x,y,z的数值

Output

过Z个月以后,共有成虫对数

Sample Input

1 2 8

Sample Output

37

题解:

从x+1到z+1循环,设a[i]为第i个月成虫的数量,b[i]为第i个月卵的数量。所以a[i] = a[i - 1] + b[i - 2](卵两个月长成成虫),b[i] = y * a[i - x](过x月产y对卵),则a[z + 1]就是答案。

初始条件为从1到x,a[i] = 1, b[i] = 0;

注意x == 0时,i初始值为1,b[i - 2] 会数组越界,这时单独判断一下。

代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline ll getnum() {
    ll ans = 0; char c; ll flag = 1;
    while (!isdigit(c = getchar()) && c != '-');
    if (c == '-') flag = -1; else ans = c - '0';
    while (isdigit(c = getchar())) ans = ans * 10 + c - '0';
    return ans * flag;
}
ll a[100], b[100];
int main() {
    ll x = getnum(), y = getnum(), z = getnum();
    a[1] = 1;
    for (int i = 1; i <= x; i++) {
        a[i] = 1;
        b[i] = 0;
    }
    for (int i = x + 1; i <= z + 1; i++) {
        if (i == 1) {
            a[i] = 1;
        }
        else a[i] = a[i - 1] + b[i - 2];
        b[i] = y * a[i - x];
    }
    if (x == z) {
        cout << "1";
    }
    else cout << a[z + 1];
    return 0;
}

B(2194):小车问题

Description

甲、乙两人同时从A地出发要尽快同时赶到B地。出发时A地有一辆小车,可是这辆小车除了驾驶员外只能带一人。已知甲、乙两人的步行速度一样,且小于车的速度。问:怎样利用小车才能使两人尽快同时到达。

Input

仅一行,三个数据分别表示AB两地的距离s,人的步行速度a,车的速度b。

Output

两人同时到达B地需要的最短时间(保留三位小数)。

Sample Input

120    5    25

Sample Output

9.600

题解:

数学题,同时到达时间最短,则走路的和开车的同时到达。设一开始开车送第一个走的距离为x,剩下距离为s - x,则答案就为x / b + (s - x) / a,把x解出来即可

解出来之后为:
[ frac{(b^2 - a^2)*s}{b^2 - 3a^2 + 2ab} ]
有个公因式b-a,所以x就等于(b + a) * s / (b + 3 * a)

代码:

#include<bits/stdc++.h>
#define maxn 1070
using namespace std;
inline int getnum() {
    int ans = 0; char c; int flag = 1;
    while (!isdigit(c = getchar()) && c != '-');
    if (c == '-') flag = -1; else ans = c - '0';
    while (isdigit(c = getchar())) ans = ans * 10 + c - '0';
    return ans * flag;
}
int main() {
    double s = getnum(), a = getnum(), b = getnum();
    double x = (b + a) * s / (b + 3 * a);
    printf("%.3lf
", x / b + (s - x) / a);
    return 0;
}

C(2196):Lights

Memory Limit: 2 Mb

Description

xrdog有个灯泡,编号从1到N。灯泡在一开始的时候都是亮着的,xrdog会对这些灯泡进行次操作,每一次操作都会选择一盏灯,并把除了这盏灯以外的灯的开关都按一下(即除了这盏灯以外的所有亮着的灯变成暗的,暗的灯变成亮的)

有趣的是,xrdog只会进行奇数次操作(即),并且最终有且仅有一盏灯是亮着的。

小砖对xrdog的这一系列操作十分的好奇,她很想知道最后亮着的这一盏灯是哪一盏。所以你能帮助一下她嘛?

Input

第一行两个整数 N(1<=N<=1018)N(1<=N<=1018) 和 M(1<=M<=106)M(1<=M<=106)

接下来一行 MM 个整数表示次操作一次是选择的哪一盏灯

Output

打印一个整数,表示最后亮着的灯的编号。

Sample Input

46 3
1 13 1

Sample Output

13

题解:

因为最后保证只有一盏灯,进行奇数次操作,所以对于某一盏灯的操作次数必须要为偶数次,否则这个灯最后就会处于打开状态,观察到空间只有2mb,不能存下来找那些是奇数次,所以对于每次操作直接对当前状态求异或即可,因为若进行偶数次操作异或结果为0,达到了找匹配的效果。

代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline ll getnum() {
    ll ans = 0; char c; int flag = 1;
    while (!isdigit(c = getchar()) && c != '-');
    if (c == '-') flag = -1; else ans = c - '0';
    while (isdigit(c = getchar())) ans = ans * 10 + c - '0';
    return ans * flag;
}
int main() {
    ll n = getnum(), m = getnum();
    ll ans = 0;
    for (int i = 1; i <= m; i++) {
        ll x = getnum();
        ans ^= x;
    }
    cout << ans;
    return 0;
}

D(2204):漫无止境的八月

Description

又双叒叕开始漫无止境的八月了,阿虚突然问起长门在这些循环中团长哪几次扎起了马尾,他有多少次抓住了蝉等等问题,长门一共回复n个自然数,每个数均不超过1500000000(1.5*10^9)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。

Input

第1行是整数n,表示回复的自然数的个数。n<=1e6
第2~n+1行每行一个自然数。

Output

包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。

Sample Input

8
2
4
2
4
5
100
2
100

Sample Output

2 3
4 2
5 1
100 2

水题,直接贴代码:

#include<bits/stdc++.h>
#define maxn 1000050
using namespace std;
int a[maxn];
inline int getnum() {
    int ans = 0; char c; int flag = 1;
    while (!isdigit(c = getchar()) && c != '-');
    if (c == '-') flag = -1; else ans = c - '0';
    while (isdigit(c = getchar())) ans = ans * 10 + c - '0';
    return ans * flag;
}
int lis[maxn];
int main() {
    int n = getnum();
    for (int i = 1; i <= n; i++) {
        a[i] = getnum();
    }
    sort(a + 1, a + n + 1);
    int cnt = 1;
    if (n == 1) {
        cout << a[1] << " " << "1" << endl;
    }
    for (int i = 2; i <= n; i++) {
        if (a[i] == a[i - 1]) {
            cnt++;
            if (i == n) {
                cout << a[i] << " " << cnt;
            }
        }
        else {
            cout << a[i - 1] << " " << cnt << endl;
            if (i == n) {
                cout << a[i] << " " << "1";
            }
            cnt = 1;
        }
    }
    return 0;
}

E(2205):Magia

Description

吼姆啦酱来救被变成魔女的纱耶香攻击的小圆辣!魔境背景中的指挥家指挥着这场表演的音乐,吼姆啦酱发现一个规律,如果过一串音符是回文的,那么这串音符会实物化来攻击她,现在给出一段音符,判断它是否是回文的。一个左右对称的自然数称为回文数,即这个数从左往右读与从右往左读是一样的,如121,686,13731,8668等都是回文数。

Input

输入一个int范围内的自然数N,判断它是否是回文数。如果是就输出这个回文数,若不是则输出-1。

Output

只有一行,N是回文数,就输出N,不是就输出-1。

Sample Input

686

Sample Output

686

更水,直接贴代码:

#include<bits/stdc++.h>
using namespace std;
char s[10000];
int main() {
    scanf("%s", s + 1);
    int len = strlen(s + 1);
    int x;
    if (len % 2 == 1) {
        x = (len - 1) / 2;
    }
    else x = len / 2;
    bool flag = true;
    for (int i = 1; i <= x; i++) {
        if (s[i] != s[len - i + 1]) {
            flag = false;
            break;
        }
    }
    if (flag) printf("%s",s + 1);
    else cout << "-1";
    return 0;
}

以上是关于csu-2018年11月月赛Round2-div2题解的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ5091 摘苹果 BZOJ2017年11月月赛 数学推导 逆元

BZOJ4883[Lydsy2017年5月月赛]棋盘上的守卫 KM算法

code+11月月赛

YACS 2023年5月月赛 甲组 T3 铺砖问题 题解

[Lydsy2017年4月月赛]抵制克苏恩

[Lydsy2017年4月月赛]抵制克苏恩题解