题目链接

A 小石的图形

简单题,但要注意PI的精度问题我是直接使用计算器,也可以使用acos(-1)或者使用c++里面的定义好的M_PI

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>

using namespace std;

const double PI = 3.1415926535897932384626433832795;

int main() {
    int n;
    cin >> n;
    printf("%.3f", n * n / PI / 2);
    return 0;
}

B 植树造林

一道很简单的贪心题,要保证到每棵树的距离最远距离最短,肯定是取最中间的树,但是偶数和奇数又不一样,奇数最中间只要一个,偶数有两个,判断一下即可。

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int main() {
    int n;
    cin >> n;
    if (n & 1)cout << 1 << endl;
    else cout << 2 << endl;
    return 0;
}

C Forsaken给学生分组

比赛时又没有认真读题,以为不能排序,其实可以排序,先从小到大排序,让每个组里的最小的尽量取所有数种最小的,最大的尽量取所有数种最大的,总结起来就是将所有数种最大的k个数和最小的k个数分别求和再相见求绝对值即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cmath>
#define int long long

using namespace std;

const int N = 100010;

int a[N];
int n, k;

signed main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++)cin >> a[i];
    sort(a, a + n, greater<int>());
    int sum = 0;
    for (int i = 0; i < k; i++)sum += a[i];
    for (int i = n - 1; i > n - 1 - k; i--)sum -= a[i];
    cout << sum << endl;
    return 0;
}

D 分数的运算

就是一道的模拟题,要细心,耐心就可以了,最主要的就是不要嫌麻烦。

#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 100010;

signed main() {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    int x1, y1, x2, y2;
    x1 = a, y1 = b, x2 = c, y2 = d;
    if (b < 0 && a > 0)a = -a, b = abs(b);
    if (d < 0 && c > 0)c = -c, d = abs(d);
    if (b != d) {
        a = a * d;
        c = c * b;
        b = d = b * d;
    }
    //cout << ' ' << a << ' ' << b << ' ' << ' ' << c <<' '<< d<<endl;
    int add1 = a + c, add2 = b;
    if (add1 == 0 || add2 == 0) {
        cout << 0 << ' ' << 0 << endl;
    } else {
        if (add1 > 0 && add2 > 0)
            cout << (add1 / __gcd(add1, add2)) << ' ' << (add2 / __gcd(add1, add2)) << endl;
        else {
            cout << '-' << abs((add1 / __gcd(add1, add2))) << ' ' << abs((add2 / __gcd(add1, add2))) << endl;
        }
    }
    int sub1 = a - c, sub2 = b;
    if (sub1 == 0 || sub2 == 0) {
        cout << 0 << ' ' << 0 << endl;
    } else {
        if (sub1 > 0 && sub2 > 0)
            cout << (sub1 / __gcd(sub1, sub2)) << ' ' << (sub2 / __gcd(sub1, sub2)) << endl;
        else cout << '-' << abs((sub1 / __gcd(sub1, sub2))) << ' ' << abs((sub2 / __gcd(sub1, sub2))) << endl;
    }
    int mul1 = x1 * x2, mul2 = y1 * y2;
    if (mul1 == 0 || mul2 == 0) {
        cout << 0 << ' ' << 0 << endl;
    } else {
        if (mul1 > 0 && mul2 > 0)
            cout << (mul1 / __gcd(mul1, mul2)) << ' ' << (mul2 / __gcd(mul1, mul2)) << endl;
        else cout << '-' << abs((mul1 / __gcd(mul1, mul2))) << ' ' << abs((mul2 / __gcd(mul1, mul2))) << endl;
    }
    int div1 = x1 * y2, div2 = x2 * y1;
    if (div1 == 0 || div2 == 0) {
        cout << 0 << ' ' << 0 << endl;
    } else {
        if (div1 > 0 && div2 > 0)
            cout << (div1 / __gcd(div1, div2)) << ' ' << (div2 / __gcd(div1, div2)) << endl;
        else cout << '-' << abs((div1 / __gcd(div1, div2))) << ' ' << abs((div2 / __gcd(div1, div2))) << endl;
    }
    return 0;
}

E 小y的旅行

这道题使用的方法好奇妙,使用并查集来维护,使用并查集的思想就是,先把不在浏览范围的景点先预处理,进行合并,最后再遍历包括景点的点,如果两个点已经在一个集合里了,如果在连一条边就会构成环了,所以把这条边删掉,答案++,如果两个点不在一个集合里,就将他们和并在一个集合里,最后输出答案即可。思路太奇妙了,感觉并查集的用处好多

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 2000010;

int fa[N];
int n, m, k;
int a[N], b[N];

int find(int x){
    if(fa[x]!=x)fa[x]=find(fa[x]);
    return fa[x];
}

int main() {
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)fa[i] = i;
    for (int i = 1; i <= m; i++) {
        cin >> a[i] >> b[i];
        if (find(a[i]) != find(b[i]) && a[i] > k && b[i] > k)
            fa[find(a[i])] = find(b[i]);
    }
    int ans = 0;
    for (int i = 1; i <= m; i++) {
        if (a[i] <= k || b[i] <= k) {
            if (find(a[i]) != find(b[i]))
                fa[find(a[i])] = find(b[i]);
            else ans++;
        }
    }
    cout << ans << endl;
    return 0;
}

F 小L的数列

G 小L的编辑器

这个题最简单的就是使用list这个容器来做(使用双链表来实现的),所以也可以使用双链表来做,而我比赛的时候是使用结构体来存是在左边还是右边,并把前一个字符作为父亲,最后输出的是从最后一个输出,并且先输出儿子,最后就可以了。

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 2000010;

string s1, s2;
struct Edge{
    char fa;
    char L,R;
}s[N];
char str[N];

int main() {
    cin >> s1 >> s2;
    for (int i = 0; i < s1.size() - 1; i++) {
        s[i].fa = s1[i];
        if (s2[i] == 'L')s[i].L = s1[i + 1], s[i].R = '#';
        else s[i].R = s1[i + 1], s[i].L = '#';
    }
    //for (int i = 0; i < s1.size() - 1; i++)cout << s[i].fa << ' ' << s[i].L << ' ' << s[i].R << endl;
    int l = 1000005, r = 1000005;
    //cout<<s1.size()-2<<endl;
    if (s[s1.size() - 2].L != '#')str[1000005] = s[s1.size() - 2].L;
    else str[1000005] = s[s1.size() - 2].R;
    //cout<<str[1000005]<<endl;
    for (int i = s1.size() - 2; i >= 0; i--) {
        if (s[i].L != '#')str[++r] = s[i].fa;
        else str[--l] = s[i].fa;
    }
    for (int i = l; i <= r; i++)cout << str[i];
    return 0;
}

使用list集合直接秒了。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<list>

using namespace std;

string a, b;

int32_t main() {
    list<char> l;
    auto pos = l.begin();
    cin >> a >> b;
    for (int i = 0; i < a.size(); i++) {
        l.insert(pos, a[i]);
        if (b[i] == 'L')pos--;
    }
    for (auto i: l)cout << i;
    return 0;
}

H 1408