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

Posted hit_yjl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

以上是关于HIT ACM 2018春 week1 codeforces.com/gym/101652 题解的主要内容,如果未能解决你的问题,请参考以下文章

HIT2372 Recoup Traveling Expenses(最长单调子序列)

2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165301

HIT1485 A Good Helper(0-1背包)

2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165237

2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165308 张士洋

2018-2019-2 网络对抗week1 Kali安装 20165333陈国超