HIT ACM 2018春 week1 codeforces.com/gym/101652 题解

A

题意:判断一个字符串是否存在偶数长度回文子串。

思路:判断是否有两个字符相等即可。O(n)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 char s[105];
45 int main() {
46     scanf("%s", s + 1);
47     int l = strlen(s + 1);
48     for (int i = 1; i < l; ++i) {
49         if (s[i] == s[i + 1]) {
50             puts("Or not.");
51             return 0;
52         }
53     }
54     puts("Odd.");
55     return 0;
56 }

B

题意:总共n种字符,判断一个n*n的方格

(1)是否每行都包含n种字符,每一列是否都包含n种字符;

(2)在满足性质(1)的情况下判断第一行和第一列元素是否严格上升

思路:按上述题意模拟即可。O(n*n)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 int n;
45 char s[41][41];
46 set<char> ss;
47 int main() {
48     while (~scanf("%d", &n)) {
49         int flag = 0;
50         for (int i = 1; i <= n; ++i) {
51             scanf("%s", s[i] + 1);
52         }
53         for (int i = 1; i <= n; ++i) {
54             ss.clear();
55             for (int j = 1; j <= n; ++j) {
56                 ss.insert(s[i][j]);
57             }
58             if (n != ss.size()) {
59                 puts("No");
60                 flag = 1;
61                 break;
62             }
63         }
64         if (flag) continue;
65         for (int j = 1; j <= n; ++j) {
66             ss.clear();
67             for (int i = 1; i <= n; ++i) {
68                 ss.insert(s[i][j]);
69             }
70             if (n != ss.size()) {
71                 puts("No");
72                 flag = 1;
73                 break;
74             }
75         }
76         if (flag) continue;
77         for (int i = 2; i <= n; ++i) {
78             if (s[i][1] < s[i - 1][1]) {
79                 puts("Not Reduced");
80                 flag = 1;
81                 break;
82             }
83         }
84         if (flag) continue;
85         for (int j = 2; j <= n; ++j) {
86             if (s[1][j] < s[1][j - 1]) {
87                 puts("Not Reduced");
88                 flag = 1;
89                 break;
90             }
91         }
92         if (flag) continue;
93         puts("Reduced");
94     }
95     return 0;
96 }

C

题意:定义f(x)为x的约数个数,求SUM(f(x))  (a <= x <= b)

思路:枚举小于等于1e6的因子,对于每一个因子y, a 到 b之间能整出y的个数为 b/y(向下取整) - a/y(向上取整)+ 1,a 到 b 之间能整除y之后剩的因子为 b/y(向下取整), ..., a/y(向上取整)的公差为-1的等差数列。

因此,在最终答案中直接加上y的个数 * y 以及除y后剩的因子和即可。但为了保证每个y只被算一次,我们应该让除y后剩余间的左端点l = max(a/y(向上取整), y)。同时,在y == l时,不要加两次y。计算量为1e6.

没理解的话可以结合代码思考,感觉代码比文字表达更清晰。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 ll a, b, ans;
45 int main() {
46     scanf("%lld%lld", &a, &b);
47     for (ll i = 1; i <= 1000000; ++i) {
48         ll x1 = (a - 1) / i + 1;
49         ll x2 = b / i;
50         if (x1 < i) x1 = i;
51         //printf("%lld %lld %lld\n", i, x1, x2);
52         if (i > b) break;
53         if (x1 > x2) continue;
54         if (x1 == i) ans -= x1;
55         ans += (x2 - x1 + 1) * i;
56         ans += (x2 - x1 + 1) * (x2 + x1) >> 1;
57     }
58     printf("%lld", ans);
59     return 0;
60 }

D

题意:定义一个序列 1, 1, 1, 1, 1, 1, ..., 2, 2, 2, 2, 2, 2, .....i, i, i, i, i,  ..., n - 1 (每个数i连续出现n - i次), 求序列中间的那个数。

思路:对于每个数i,第一次出现的位置都可以O(1)求出来(等差数列求和),我们又可以求出序列总元素个数以及中间数的位置,因此二分判定就好了。O(logn)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 ll n;
45 ll cal(ll x) {
46     return (n + n - 1 - x) * x >> 1;
47 }
48 int main() {
49     scanf("%lld", &n);
50     ll cnt = ((n * (n - 1) >> 1) + 1) >> 1;
51     ll ans = 0, s = 0, e = n, mi;
52     while (s <= e) {
53         mi = s + e >> 1;
54         if (cal(mi) < cnt) {
55             s = (ans = mi) + 1;
56         } else {
57             e = mi - 1;
58         }
59     }
60     printf("%lld", ans + 1);
61     return 0;
62 }

E

题意:已知一个机器人的速度,起点终点都在x轴方向,中间有一些竖向的传送带,各个速度都已知, 判定一下机器人到终点的最短时间。

思路:对y轴移动距离列方程,把机器人速度分解,vy * L / vx = SUM(vi * li / vx)。vx可以约掉。因此O(1)求出vy, vx也可以求出。复杂度O(1)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 int n;
45 double x, V, v[105], l[105], r[105];
46 int main() {
47     double cnt = 0;
48     scanf("%d%lf%lf", &n, &x, &V);
49     for (int i = 1; i <= n; ++i) {
50         scanf("%lf%lf%lf", &l[i], &r[i], &v[i]);
51         cnt += (r[i] - l[i]) * v[i];
52     }
53     double vy = fabs(cnt / x);
54     if (vy >= V) {
55         puts("Too hard");
56         return 0;
57     } else {
58         double vx = sqrt(V * V - vy * vy);
59         if (vx * 2 <= V + EPS) {
60             puts("Too hard");
61         } else {
62             printf("%.3f\n", x / vx);
63         }
64     }
65     return 0;
66 }

F

题意:对于一个只有RB两种字符的字符串,求出一个子串使得‘R’, ‘B’两种字符数量的差值最大。

思路:可以将问题拆开。一种是求R的数量-B的数量最多,另一个是B的数量-R的数量最大。考虑每个单独的问题,比如要求R-B尽可能多,我们线性扫一遍,如果当前R的数量大于等于B,那么我们遇见R就加1, 遇见B就减1。

如果R比B少,那么我们为了使这个差值尽可能大,显然要舍弃之前选的那段序列,而从当前位置重新开始取。复杂度O(n)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 int n;
45 char s[100015];
46 void solve(int &ma, int &l1, int &r1, char c) {
47     for (int i = 1, j = 1, cnt = 0, flag = 1; j <= n; ++j) {
48         if (!cnt) {
49             if (c == s[j]) {
50                 ++cnt;
51                 if (cnt > ma) {
52                     l1 = r1 = j;
53                     ma = cnt;
54                 }
55                 if (flag) {
56                     i = j;
57                     flag = 0;
58                 }
59             } else {
60                 flag = 1;
61                 continue;
62             }
63         } else {
64             if (c == s[j]) {
65                 ++cnt;
66                 if (cnt > ma) {
67                     r1 = j;
68                     l1 = i;
69                     ma = cnt;
70                 }
71             } else {
72                 --cnt;
73             }
74         }
75     }
76 }
77 int main() {
78     scanf("%s", s + 1);
79     n = strlen(s + 1);
80     int ma1 = 0, l1 = 0, r1 = 0, ma2 = 0, l2 = 0, r2 = 0;
81     solve(ma1, l1, r1, ‘B‘);
82     solve(ma2, l2, r2, ‘R‘);
83     int ans_l, ans_r;
84     if (ma1 > ma2 || (ma1 == ma2 && (l1 < l2 || (l1 == l2 && r1 < r2)))) {
85         ans_l = l1, ans_r = r1;
86     } else {
87         ans_l = l2, ans_r = r2;
88     }
89     printf("%d %d", ans_l, ans_r);
90     return 0;
91 }

G

题意:一个有向图中每条边都有一段区间,表示权限,只有x在这段区间内才可以经过这条边,求出所有能从起点走到终点的x。

思路:我们把所有的区间统一改成左闭右开的形式。把所有的时间段的端点提取出来并从小到大排序。然后考虑每个时间点ti,如果ti能从起点到达终点,那么[t(i), t(i + 1))这段区间内的所有时间点都可以到达终点,因为如果t(i)可以到达终点,那么它肯定不能只是一个时间段的右开端点,所以他至少是一个左闭端点,因此其向后取的那一小段时间段一定可取;如果t(i)不能到达,则显然只是一个右开端点,因此不取它后面的一段区间。O(mlogm + m*(m + n))。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 int n, m, k, s, t, ans;
45 struct edge {
46     int v, l, r;
47     edge () {}
48     edge (int v, int l, int r) : v(v), l(l), r(r) {}
49 };
50 vector<edge> E[1015];
51 vector<int> timestamps;
52 bool visit[1015];
53 void dfs(int x, int timestamp) {
54     visit[x] = true;
55     for (int i = 0; i < E[x].size(); ++i) {
56         int v = E[x][i].v;
57         int l = E[x][i].l;
58         int r = E[x][i].r;
59         if (l <= timestamp && timestamp <= r && !visit[v]) {
60             dfs(v, timestamp);
61         }
62     }
63 }
64 int main() {
65     scanf("%d%d%d%d%d", &n, &m, &k, &s, &t);
66     while (m--) {
67         int a, b, c, d;
68         scanf("%d%d%d%d", &a, &b, &c, &d);
69         E[a].pb(edge(b, c, d));
70         timestamps.pb(c);
71         timestamps.pb(d + 1);
72     }
73     sort(timestamps.begin(), timestamps.end());
74     int number_Of_Timestamps = unique(timestamps.begin(), timestamps.end()) - timestamps.begin();
75     for (int i = 0; i < number_Of_Timestamps - 1; ++i) {
76         int timestamp = timestamps[i];
77         clr(visit, false);
78         dfs(s, timestamp);
79         if (visit[t]) {
80             ans += timestamps[i + 1] - timestamps[i];
81         }
82     }
83     printf("%d", ans);
84     return 0;
85 }

H

题意:改变一个不均匀骰子的一个面的点数(可以为实数),使得其期望为3.5

思路:求出期望差值,除以概率最大的那个面就是改变的最小值。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 double p[11], sum, ma;
45 int main() {
46     for (int i = 1; i <= 6; ++i) {
47         scanf("%lf", &p[i]);
48         sum += p[i] * i;
49         ma = max(ma, p[i]);
50     }
51     printf("%.3f", fabs(sum - 3.5) / ma);
52     return 0;
53 }

I

题意:一个无限长字符串上一系列插入删除操作,问两组操作是否等价。

思路:用个链表暴力n*n模拟?(这题我还没写,这几天写完更新)

J

题意:一个n * m的方格上有‘B’, ‘R‘, ‘.‘分别表示黑色,红色,以及目前为空着。要求每个B左上角的所有块都必须为黑色,R右下角的所有块都必须为红色。

思路:你可以先n*n*m*m暴力利用所有已知的R,B信息把方格填充,这样左上角以及右下角都被确定,待处理的只有中间空的一部分,这个中间部分满足列数从左到右时,其相应待确定的行数单调递减。

因此,我们用dp[j][i]表示第j列第i行为此列最后一个黑色块,那么dp[j][i] = SUM(dp[j - 1][k]),其中k从i到n。复杂度O(n * n * m * m),可以优化到O(n*m)。

  1 #include <iostream>
  2 #include <fstream>
  3 #include <sstream>
  4 #include <cstdlib>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <queue>
 11 #include <stack>
 12 #include <vector>
 13 #include <set>
 14 #include <map>
 15 #include <list>
 16 #include <iomanip>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <bitset>
 20 #include <ctime>
 21
 22 using namespace std;
 23
 24 #define pau system("pause")
 25 #define ll long long
 26 #define pii pair<int, int>
 27 #define pb push_back
 28 #define mp make_pair
 29 #define clr(a, x) memset(a, x, sizeof(a))
 30
 31 const double pi = acos(-1.0);
 32 const int INF = 0x3f3f3f3f;
 33 const int MOD = 1e9 + 7;
 34 const double EPS = 1e-9;
 35
 36 /*
 37 #include <ext/pb_ds/assoc_container.hpp>
 38 #include <ext/pb_ds/tree_policy.hpp>
 39
 40 using namespace __gnu_pbds;
 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
 42 */
 43
 44 int n, m;
 45 char mmp[35][35];
 46 ll dp[35][35];
 47
 48 int main() {
 49     scanf("%d%d", &n, &m);
 50     for (int i = 1; i <= n; ++i) {
 51         scanf("%s", mmp[i] + 1);
 52     }
 53     for (int i = 1; i <= n; ++i) {
 54         for (int j = 1; j <= m; ++j) {
 55             if (‘B‘ == mmp[i][j]) {
 56                 for (int k = 1; k <= i; ++k) {
 57                     for (int l = 1; l <= j; ++l) {
 58                         if (‘R‘ == mmp[k][l]) {
 59                             puts("0");
 60                             return 0;
 61                         }
 62                         mmp[k][l] = ‘B‘;
 63                     }
 64                 }
 65             }
 66             if (‘R‘ == mmp[i][j]) {
 67                 for (int k = i; k <= n; ++k) {
 68                     for (int l = j; l <= m; ++l) {
 69                         if (‘B‘ == mmp[k][l]) {
 70                             puts("0");
 71                             return 0;
 72                         }
 73                         mmp[k][l] = ‘R‘;
 74                     }
 75                 }
 76             }
 77         }
 78     }
 79     for (int i = n; ~i; --i) {
 80         if (‘R‘ == mmp[i][1]) continue;
 81         dp[i][1] = 1;
 82         if (‘B‘ == mmp[i][1]) break;
 83     }
 84     for (int j = 2; j <= m; ++j) {
 85         for (int i = n; ~i; --i) {
 86             if (‘R‘ == mmp[i][j]) continue;
 87             for (int k = i; k <= n; ++k) {
 88                 dp[i][j] += dp[k][j - 1];
 89             }
 90             if (‘B‘ == mmp[i][j]) break;
 91         }
 92     }
 93     /*for (int i = 0; i <= n; ++i) {
 94         for (int j = 1; j <= m; ++j) {
 95             printf("%d ", dp[i][j]);
 96         }
 97         puts("");
 98     }*/
 99     ll ans = 0;
100     for (int i = 0; i <= n; ++i) {
101         ans += dp[i][m];
102     }
103     printf("%lld", ans);
104     return 0;
105 }

K

题意:美国国旗是有s个星,所有奇数行星数都为x, 所有偶数行星数都为y, x等于y或y + 1。

思路:枚举三种情况,(1) x == y (2) x == y + 1总行数为偶数 (3) x == y + 1总行数为奇数。最后排下序,复杂度O(S + sqrt(s) * logs)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 set<pii> ss;
45 int s;
46 int main() {
47     scanf("%d", &s);
48     for (int i = 2; i < s; ++i) {
49         if (s % i == 0) {
50             ss.insert(mp(i, i));
51         }
52     }
53     for (int i = 2; i < s; ++i) {
54         if ((s - i) % (i + i - 1) == 0 || (s % (i + i - 1) == 0) ) {
55             ss.insert(mp(i, i - 1));
56         }
57     }
58     printf("%d:\n", s);
59     for (set<pii>::iterator it = ss.begin(); it != ss.end(); ++it) {
60         int x = (*it).first, y = (*it).second;
61         printf("%d,%d\n", x, y);
62     }
63     return 0;
64 }

L

题意:已知x, k, p, 求x * n + k * p / n的最小值

思路:对号函数,因为n为整数,输出sqrt(k * p / x)左右两个整点对应函数值的最小值。O(1)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 int k, p, x;
45 double cal(int n) {
46     return 1.0 * x * n + 1.0 * k * p / n;
47 }
48 int main() {
49     scanf("%d%d%d", &k, &p, &x);
50     int n = sqrt((k * p + 0.5) / x);
51     printf("%.3f\n", min(cal(n), cal(n + 1)));
52     return 0;
53 }

M

题意:给一个n,求出大于n中第一个不含0的数。

思路:从n+1开始枚举即可,复杂度O(n / 10)。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <string>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <list>
16 #include <iomanip>
17 #include <cctype>
18 #include <cassert>
19 #include <bitset>
20 #include <ctime>
21
22 using namespace std;
23
24 #define pau system("pause")
25 #define ll long long
26 #define pii pair<int, int>
27 #define pb push_back
28 #define mp make_pair
29 #define clr(a, x) memset(a, x, sizeof(a))
30
31 const double pi = acos(-1.0);
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 const double EPS = 1e-9;
35
36 /*
37 #include <ext/pb_ds/assoc_container.hpp>
38 #include <ext/pb_ds/tree_policy.hpp>
39
40 using namespace __gnu_pbds;
41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
42 */
43
44 int n;
45 bool ok(int x) {
46     while (x) {
47         if (x % 10 == 0) return false;
48         x /= 10;
49     }
50     return true;
51 }
52 int main() {
53     scanf("%d", &n);
54     for (int i = n + 1; ; ++i) {
55         if (ok(i)) {
56             printf("%d\n", i);
57             return 0;
58         }
59     }
60
61     return 0;
62 }

原文地址:https://www.cnblogs.com/BIGTOM/p/8544267.html

时间: 2024-10-24 07:04:27

HIT ACM 2018春 week1 codeforces.com/gym/101652 题解的相关文章

2018春招-今日头条笔试题-第三题(python)

题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 本题的做法最重要的应该是如何拼出'1234567890',对于输入表达试获得对应的结果利用python内置函数eval()即可以实现.利用5个字符串来表达'1234567890',如下(为了好看,里面加了tab空格符) '66666 ....6 66666 66666 6...6 66666 66666 66666 66666 66666''6...6 ....6 ....6 ....6 6...6 6.... 6

http://codeforces.com/gym/100623/attachments E题

http://codeforces.com/gym/100623/attachments E题第一个优化它虽然是镜像对称,但它毕竟是一一对称的,所以可以匹配串和模式串都从头到尾颠倒一下第二个优化,与次数无关,所以排个序就完事了 1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<

http://codeforces.com/gym/100623/attachments H题

http://codeforces.com/gym/100623/attachments H题已经给出来的,包括后来添加的,都累加得到ans,那么从1-ans都是可以凑出来的,如果ans<a[now]-1,那么就添加一个ans+1,然后继续操作. 1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath>

codeforces A. Supercentral Point 题解

One day Vasya painted a Cartesian coordinate system on a piece of paper and marked some set of points(x1,?y1),?(x2,?y2),?...,?(xn,?yn). Let's define neighbors for some fixed point from the given set (x,?y): point (x',?y') is (x,?y)'s right neighbor,

codeforces New Year Present 题解

The New Year is coming! That's why many people today are busy preparing New Year presents. Vasily the Programmer is no exception. Vasily knows that the best present is (no, it's not a contest) money. He's put n empty wallets from left to right in a r

codeforces Sereja and Dima 题解

Sereja and Dima play a game. The rules of the game are very simple. The players have n cards in a row. Each card contains a number, all numbers on the cards are distinct. The players take turns, Sereja moves first. During his turn a player can take o

codeforces D. Ice Sculptures 题解

The Berland University is preparing to celebrate the 256-th anniversary of its founding! A specially appointed Vice Rector for the celebration prepares to decorate the campus. In the center of the campus n ice sculptures were erected. The sculptures

Educational Codeforces Round 64部分题解

Educational Codeforces Round 64部分题解 A 题目大意:给定三角形(高等于低的等腰),正方形,圆,在满足其高,边长,半径最大(保证在上一个图形的内部)的前提下. 判断交点个数是否有限,如果有限,输出. 很明显当正方形套三角形或者三角形套正方形是交点个数是无限的(因为有一条边相交) 其他图形的嵌套交点个数比较好判断,不多赘述 但是注意坑点: 当按照矩形,园,三角这样的顺序是,三角与圆的一个交点是与圆和正方形的交点重合的,判一下就好了 #include<cstdio>

Codeforces 7E - Defining Macros 题解

目录 Codeforces 7E - Defining Macros 题解 前言 做法 程序 结尾 Codeforces 7E - Defining Macros 题解 前言 开始使用博客园了,很想写点东西.(逃 这是一道Codeforces题目. 做法 一道大模拟 相信大家都看得懂题目意思,我就不赘述了. 首先我们读进来\(n\)行,对于每一行,我们把它初步分成一下四块内容: #号 define 宏的名字 宏的表达式 注意:#和define中间可能会有空格,define和宏的名字,宏的名字和宏