2019牛客暑期多校训练营 第五场

应该是最简单的一场了。

题目链接:https://ac.nowcoder.com/acm/contest/885#question


A:

显然输出n个n串在一起是答案。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 int t;
21 
22 int main() {
23     scanf("%d", &t);
24     while (t--) {
25         int n; scanf("%d", &n);
26         for (int i = 1; i <= n; i++) printf("%d", n);
27         puts("");
28     }
29     return 0;
30 }
View Code

B:

普通的快速幂绝对不行,要十分幂(log10)级别。完全就是十分幂模板题了。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 1e6 + 10;
21 int x0, x1, a, b, mod;
22 char s[maxn];
23 
24 struct Matrix {
25     ll mem[2][2];
26     void init() {
27         memset(mem, 0, sizeof(mem));
28     }
29     Matrix operator*(const Matrix &rhs)const {
30         Matrix ret; ret.init();
31         for (int i = 0; i < 2; i++) {
32             for (int j = 0; j < 2; j++) {
33                 for (int k = 0; k < 2; k++)
34                     ret.mem[i][j] += mem[i][k] * rhs.mem[k][j];
35                 ret.mem[i][j] %= mod;
36             }
37         }
38         return ret;
39     }
40 } mAns, mBase;
41 
42 ll solve(char *s) {
43     int len = strlen(s);
44     for (int i = len - 1; i >= 0; i--) {
45         int curr = s[i] - '0';
46         while (curr--) mAns = mAns * mBase;
47         Matrix tmp = mBase * mBase;
48         mBase = tmp * tmp;
49         mBase = mBase * mBase * tmp;
50     }
51     return mAns.mem[0][1];
52 }
53 
54 int main() {
55     mAns.init(), mBase.init();
56     scanf("%d%d%d%d", &x0, &x1, &a, &b);
57     scanf("%s %lld", s, &mod);
58     mAns.mem[0][0] = x1, mAns.mem[0][1] = x0;
59     mBase.mem[0][0] = a, mBase.mem[0][1] = 1, mBase.mem[1][0] = b;
60     ll ans = solve(s);
61     printf("%lld\n", ans);
62     return 0;
63 }
View Code

C:

给定一个递推序列xi=(a*xi-1+b)%mod,有q次查询,每次查询给定一个值p,找出最小的下标i,使得xi=p。

显然a≠0时xi与xi-1一一对应,可以直接套用大步小步算法(baby steps giant steps)。

D:

序列x和序列y从某个位置后开始会出现循环,但循环节不一样。

E:

状压dp。

F:

二分图最大独立集。

G:

考虑dp。对于所有长度大于m的合法的subsequence,用组合数计算;长度等于m的合法的subsequence,判断s最高位是否大于t最高位。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int mod = 998244353, maxn = 3e3 + 10;
21 int inv[maxn], fac[maxn], fiv[maxn], dp[2][maxn];
22 
23 int add(int a, int b) {
24     return a + b < mod ? a + b : a + b - mod;
25 }
26 
27 int mul(int a, int b) {
28     return (ll)a * b % mod;
29 }
30 
31 int C(int n, int m) {
32     return n < m ? 0 : mul(fac[n], mul(fiv[m], fiv[n - m]));
33 }
34 
35 int main() {
36     inv[0] = inv[1] = fac[0] = fac[1] = fiv[0] = fiv[1] = 1;
37     for (int i = 2; i < maxn; i++) {
38         inv[i] = mul(inv[mod % i], mod - mod / i);
39         fac[i] = mul(fac[i - 1], i);
40         fiv[i] = mul(fiv[i - 1], inv[i]);
41     }
42     dp[0][0] = 1;
43     int t; scanf("%d", &t);
44     while (t--) {
45         int n, m; char s[maxn], t[maxn];
46         scanf("%d%d", &n, &m); cin >> s >> t;
47         int ans = 0;
48         for (int i = 0; i < n; i++)
49             if (s[i] != '0') {
50                 for (int j = m; i + j < n; j++)
51                     ans = add(ans, C(n - i - 1, j));
52             }
53         int *dp0 = dp[0], *dp1 = dp[1];
54         size_t size = (m + 1) << 2;
55         memset(dp0, 0, size);
56         for (int i = 1; i <= n; i++) {
57             memcpy(dp1, dp0, size);
58             for (int j = 1; j <= m; j++) {
59                 // 要拿当前位
60                 if (s[n - i] > t[m - j]) dp1[j] = add(dp1[j], C(i - 1, j - 1));
61                 // 不拿当前位
62                 if (s[n - i] == t[m - j]) dp1[j] = add(dp1[j], dp0[j - 1]);
63             }
64             swap(dp0, dp1);
65         }
66         printf("%d\n", add(ans, dp0[m]));
67     }
68     return 0;
69 }
View Code

H:

因为字母出现顺序满足偏序性质,所以可以考虑拓扑排序。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 1e5 + 10;
21 struct Edge {
22     int to, next;
23     Edge() {}
24     Edge(int to, int next): to(to), next(next) {}
25 } edge[maxn * 10];
26 int head[maxn], inDeg[maxn], tot = 0, realMem[maxn * 10];
27 char str[maxn], op[maxn];
28 vector<int>vec, realPos[20];
29 
30 void addEdge(int u, int v) {
31     edge[tot].to = v;
32     edge[tot].next = head[u];
33     inDeg[v]++;
34     head[u] = tot++;
35 }
36 
37 int topologicalSort(int n) {
38     queue<int>q;
39     for (int i = 1; i <= n; i++)
40         if (!inDeg[i]) q.push(i); // 找最小的点
41     while (!q.empty()) {
42         int u = q.front();
43         q.pop();
44         vec.pb(u);
45         for (int i = head[u]; ~i; i = edge[i].next) {
46             int v = edge[i].to;
47             inDeg[v]--;
48             if (!inDeg[v]) q.push(v);
49         }
50     }
51     if (n == vec.size()) return 1; // 如果构建出来的图大小也为n,说明有解
52     else return 0;
53 }
54 
55 int main() {
56     int n, m; scanf("%d%d", &n, &m);
57     m = m * (m - 1) >> 1;
58     for (int i = 0; i < maxn; i++) head[i] = -1;
59     int realLen = 0;
60     while (m--) {
61         int len;
62         scanf("%s %d", op, &len);
63         if (len != 0) scanf("%s", str);
64         int lastElement = -1;
65         int times[26];
66         memset(times, 0, sizeof(times));
67         for (int i = 0; i < len; i++) {
68             int currElement = str[i] - 'a';
69             times[currElement]++; // 统计当前字符串中当前字母出现次数
70             if (realPos[currElement].size() < times[currElement]) { // 如果当前字符串中的某个字母出现次数超出了之前的统计,说明该字母有更多个
71                 realPos[currElement].pb(++realLen);
72                 realMem[realLen] = currElement;
73             }
74             if (lastElement != -1) addEdge(lastElement, realPos[currElement][times[currElement] - 1]);
75             lastElement = realPos[currElement][times[currElement] - 1];
76         }
77     }
78     if (n != realLen) return puts("-1"), 0;
79     if (topologicalSort(n))
80         for (int i = 0; i < vec.size(); i++)
81             printf("%c", 'a' + realMem[vec[i]]);
82     else puts("-1");
83     return 0;
84 }
View Code

I:

不妨把三角形的一个定点固定在原点,并让一条边尽可能地贴近y轴,分为两种情况:完全贴合和不能贴合。

此时可以计算出在矩形边界的第二个点和第三个点,检验第三个点是否在矩形内部即可。

枚举所有情况,总共6种。注意答案输出顺序固定为XYZ三点。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-10
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 #define Point pair<double, double>
21 const double pi = acos(-1.0);
22 int w, h;
23 
24 int solve(int a, int b, int c, Point &x, Point &y) {
25     double alpha = 0;
26     if (a <= h) x.first = 0, x.second = (double)a;
27     else {
28         x.first = sqrt((double)a * a - (double)h * h), x.second = (double)h;
29         alpha = acos((double)h / (double)a);
30     }
31     double beta = acos((double)(a * a + b * b - c * c ) / (2.0 * a * b));
32     double gamma = pi / 2.0 - alpha - beta;
33     y.first = cos(gamma) * b, y.second = sin(gamma) * b;
34     if (y.first - w > eps || y.second - h > eps || y.first < -eps || y.second < -eps) return 0;
35     return 1;
36 }
37 
38 int main() {
39     int t; scanf("%d", &t);
40     while (t--) {
41         Point x, y, z;
42         int a, b, c;
43         scanf("%d%d%d%d%d", &w, &h, &a, &b, &c);
44         if (solve(b, c, a, x, y) || solve(c, b, a, y, x)) {
45             z.first = z.second = 0; goto mark;
46         }
47         if (solve(a, c, b, x, z) || solve(c, a, b, z, x)) {
48             y.first = y.second = 0; goto mark;
49         }
50         if (solve(a, b, c, y, z) || solve(b, a, c, z, y)) {
51             x.first = x.second = 0; goto mark;
52         }
53 mark:
54         printf("%.10f %.10f %.10f %.10f %.10f %.10f\n", x.first, x.second, y.first, y.second, z.first, z.second);
55     }
56     return 0;
57 }
View Code

J:

先判断无解的情况,再利用dp+dfs求解。 

posted @ 2019-08-01 23:26  JHSeng  阅读(268)  评论(0编辑  收藏  举报