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; } |
题意:给定两门课的不同课程安排,各选择一个,使得两门课的间隔时间最短。
解法:求两门课最小右界(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; } |