Codeforces Round #404 (Div. 2)

A - Anton and Polyhedrons 【模拟】

简单题。map<string,int>mp累计字符串权值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <bits/stdc++.h>
#define scf0(a) scanf("%s", &a)
#define scf1(a) scanf("%d", &a)
#define scf2(a, b) scanf("%d%d", &a, &b)
#define scf3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scf4(a, b, c, d) scanf("%d%d%d%d", &a, &b, &c, &d)
#define MEM(a, b) memset(a, b, sizeof(a))
#define PII pair<int, int>
using namespace std;
int main() {
    map<string,int>mp;
    mp["Tetrahedron"] = 4;
    mp["Cube"] = 6;
    mp["Octahedron"] = 8;
    mp["Dodecahedron"] = 12;
    mp["Icosahedron"] = 20;
    string op;
    int n;
    cin >> n;
    int sum = 0;
    while(n--) {
        cin >> op;
        sum += mp[op];
    }
    cout << sum << endl;
}

B - Anton and Classes 【贪心】

题意:给定两门课的不同课程安排,各选择一个,使得两门课的间隔时间最短。

解法:求两门课最小右界(minn、minm)和最大左界(maxn、maxm)。结果ans = max( 0, max(maxn-minm, maxm-minn) )

(做的时候初始化minn写成0x3f3f3f,差了一个3f...粗心啊)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <bits/stdc++.h>
#define scf0(a) scanf("%s", &a)
#define scf1(a) scanf("%d", &a)
#define scf2(a, b) scanf("%d%d", &a, &b)
#define scf3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scf4(a, b, c, d) scanf("%d%d%d%d", &a, &b, &c, &d)
#define MEM(a, b) memset(a, b, sizeof(a))
#define PII pair<int, int>
using namespace std;
int main() {
    int n, m, x, y;
    scf1(n);
    int maxn = -1, minn = 0x3f3f3f3f;
    for(int i = 0; i < n; i++) {
        scf2(x,y);
        maxn = max(maxn, x);
        minn = min(minn, y);
    }
    scf1(m);
    int maxm = -1, minm = 0x3f3f3f3f;
    for(int i = 0; i < m; i++) {
        scf2(x, y);
        maxm = max(maxm, x);
        minm = min(minm, y);
    }
    int ans = maxm - minn;
    ans = max(ans, maxn - minm);
    cout << ( ans > 0 ? ans : 0) << endl;
}

C - Anton and Fairy Tale 【数学题】

题意:仓库容量n,每天补充粮食m份但不能超过仓库容量,第i天麻雀吃掉i份粮食,求哪一天仓库会没有粮食

第 i 天      开始      结束

1             n          n-1

2             n          n-2

3             n          n-3

..

m            n          n-m

-------------------------------

m+1        n          n-m-1

m+2        n-1       n-m-3

..

m+x        n-x       n - m - x(x+1)/2 <= 0

一、直接解方程做法:

所以可以把时间分成两部分:1.前m天(包括第m天)2.第m天以后

解方程   n - m - x(x+1)/2 得 x = ( -1+sqrt(1+8(n-m)) ) / 2

然后!!注意精度问题。。

1.手写个sqrt避免例如sqrt(9)=2.9999向下取整得到2的情况。。

2.总之得到一个手算精确的结果,然后向上取整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
using namespace std;
long long SQRT(long long x) {
    long long temp = sqrt(x);
    temp -= 5;
    for(temp;;temp++) {
        if(temp * temp == x) {
            return temp;
        }
        if(temp * temp > x) {
            return temp - 1;
        }
    }
}
int main() {
    long long n, m;
    cin >> n >> m;
    if(n <= m ) {
        cout << n << endl;
        return 0;
    }
    long long x = 1 + 8 * (n - m);
    long long temp = SQRT(x); //求得一个准确的sqrt
    if(temp * temp == x) {   //如果sqrt后是整数
        long long ans = -1 + temp;
        if(ans % 2 == 0)
            cout << ans / 2 + m  << endl;
        else
            cout << ans / 2 + m + 1 << endl;
    }
 
    else {  //sqrt后不是整数,那肯定要向上取整
        long long ans = -1 + temp;
        cout << ans / 2 + m + 1<< endl;
    }
}

但因为sqrt精度丢失只会变小,所以也可以用直接用sqrt得出一个ans,然后judge一下ans是否满足题意( ans*(ans+1)/2 >= n - m )即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <bits/stdc++.h>
using namespace std;
int main() {
    long long n, m;
    cin >> n >> m;
    if(n <= m ) {
        cout << n << endl;
        return 0;
    }
    long long x = ( sqrt ( 1 + 8 * (n - m) ) - 1) / 2;
    while(1) {
        long long temp = (x + 1) * x / 2;
        if(temp >= n - m) {
            cout << x + m << endl;
            return 0;
        }
        x++;
    }
}


 

二、二分结果+judge做法:求左界。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <bits/stdc++.h>
using namespace std;
long long n, m;
bool judge(unsigned long long x) {
    if( x * (x + 1) >= 2 * (n - m) ) return true;
    else return false;
}
int main() {
    cin >> n >> m;
    if(n <= m) {
        cout << n << endl;
        return 0;
    }
    long long low = 0LL, high = 1LL << 31;
    while(low < high) {
        long long mid = low + high >> 1;
        if(judge(mid)) high = mid;
        else low = mid+1;
    }
    cout <<high + m << endl;
}
原文地址:https://www.cnblogs.com/bestwzh/p/6562410.html