2019 HDOJ Multi-University Training Contest Stage 5(杭电多校)

可能会有人问“你的杭电多校4呢?”。别问,问就是在写了.jpg

题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=852


D:

把所有函数按零点位置排序,然后从左往右检查每对相邻零点形成的区间的解,并验证之。

 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 Function {
22     ll a, b;
23     Function(int _a = 1, int _b = 0): a(_a), b(_b) {
24         if (a < 0) a = -a, b = -b;
25     }
26     void simplicate() {
27         if (!b) a = 1;
28         else {
29             ll gg = __gcd(a, abs(b));
30             a /= gg, b /= gg;
31         }
32     }
33     bool operator<(const Function &rhs) const {
34         return b * rhs.a < a * rhs.b;
35     }
36     bool operator<=(const Function &rhs) const {
37         return b * rhs.a <= a * rhs.b;
38     }
39     bool operator==(const Function &rhs) const {
40         return b * rhs.a == a * rhs.b;
41     }
42 } f[maxn];
43 int tot;
44 
45 void solve() {
46     int n; ll c; scanf("%d%lld", &n, &c); tot = 0;
47     for (int i = 0; i < n; i++) {
48         int a, b; scanf("%d%d", &a, &b);
49         b = -b;
50         if (!a) c -= abs(b);
51         else {
52             if (a < 0) a = -a, b = -b;
53             f[tot++] = Function(a, b);
54         }
55     }
56     if (!tot) {
57         if (!c) puts("-1"); else puts("0");
58         return;
59     }
60     sort(f, f + tot);
61     vector<Function> func;
62     ll sumA = 0, sumB = 0;
63     for (int i = 0; i < tot; i++)
64         sumA += f[i].a, sumB += f[i].b;
65     {
66         Function res(sumA, c + sumB);
67         if (f[tot - 1] <= res) func.pb(res);
68     }
69     for (int i = tot - 1; i >= 0; i--) {
70         sumA -= f[i].a * 2, sumB -= f[i].b * 2;
71         if (!sumA) {
72             if (!(sumB + c)) {
73                 if (f[i - 1] < f[i]) {
74                     puts("-1");
75                     return;
76                 }
77             }
78             continue;
79         }
80         Function res(sumA, c + sumB);
81         if (i) {
82             if (res <= f[i] && f[i - 1] <= res)
83                 func.pb(res);
84         } else if (res <= f[i]) func.pb(res);
85     }
86     rep0(i, 0, (int)func.size()) func[i].simplicate();
87     sort(func.begin(), func.end());
88     func.resize(distance(func.begin(), unique(func.begin(), func.end())));
89     printf("%d", (int)func.size());
90     for (auto i : func) printf(" %lld/%lld", i.b, i.a);
91     puts("");
92 }
93 int main() {
94     int caseNum; scanf("%d", &caseNum);
95     while (caseNum--) solve();
96     return 0;
97 }
View Code

E:

虽然n!在n较大时会增长得很快,但这题k最大只有1e4,所以可以通过暴力dfs枚举答案。

答案的规律很显然,就是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 const int maxn = 10;
21 int n, k, d[maxn], vis[maxn], tt = 0;
22 
23 int dfs(int currBit, int lowPoint, int highPoint) {
24     if (currBit == n) {
25         if (!(--k)) {
26             vector<int>ans;
27             for (int i = 0; i < n; i++) ans.pb(d[i] - lowPoint + 1);
28             rep0(i, 0, (int)ans.size()) {
29                 printf("%d", ans[i]);
30                 if (i != (int)ans.size() - 1) printf(" "); else puts("");
31             }
32             return 1;
33         }
34         return 0;
35     }
36     for (int i = highPoint - n + 1; i <= lowPoint + n - 1; i++) {
37         if (vis[i]) continue;
38         vis[i] = 1; d[currBit] = i;
39         if (dfs(currBit + 1, min(lowPoint, i), max(highPoint, i))) {
40             vis[i] = 0; return 1;
41         }
42         vis[i] = 0;
43     }
44     return 0;
45 }
46 
47 int main() {
48     int t; scanf("%d", &t);
49     while (t--) {
50         tt++;
51         scanf("%d%d", &n, &k);
52         d[0] = n, vis[n] = 1;
53         dfs(1, n, n);
54         vis[n] = 0;
55     }
56     return 0;
57 }
View Code 

F:

队友一眼exKMP题,我还没反应过来。还因为直接cin白给了一发,不应该。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<cstring>
 7 
 8 using namespace std;
 9 
10 const int maxn = 2000000;
11 char s[maxn];
12 int Next[maxn];
13 typedef long long ll;
14 void pre_EKMP(int m) {
15     Next[0] = m;
16     int j = 0;
17     while (j + 1 < m && s[j] == s[j + 1]) j++;
18     Next[1] = j;
19     int k = 1;
20     for (int i = 2; i < m; i++) {
21         int p = Next[k] + k - 1;
22         int L = Next[i - k];
23         if (i + L < p + 1) {
24             Next[i] = L;
25         } else {
26             j = max(0, p - i + 1);
27             while (i + j < m && s[i + j] == s[j]) j++;
28             Next[i] = j;
29             k = i;
30         }
31     }
32 }
33 int main() {
34     ios::sync_with_stdio(false);
35     cin.tie(0);
36     cout.tie(0);
37     int T;
38     cin >> T;
39     while (T--) {
40         cin >> s;
41         int len = strlen(s);
42         pre_EKMP(len);
43         ll ans = 0;
44         for (int i = 1; i < len; i++) {
45             ans += Next[i];
46             if (i + Next[i] < len) {
47                 ans++;
48             }
49         }
50         cout << ans << endl;
51     }
52     return 0;
53 }
View Code

G:

对n==10和n==11的情况打个表就很清楚了

对于不在顶点处的元素,显然a[i][j]=a[i][j-1]+a[i][j-3];对于a[1][n]有a[1][n]=a[1][n+1]。

 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, mod = 998244353;
21 int t, a[maxn];
22 
23 int main() {
24     a[1] = 0, a[2] = 1, a[3] = 1;
25     for (int i = 4; i < maxn; i++) a[i] = (a[i - 1] + a[i - 3]) % mod;
26     scanf("%d", &t);
27     while (t--) {
28         int n, x, y; scanf("%d%d%d", &n, &x, &y);
29         if (x > y) swap(x, y);
30         int fixY = x != 1 ? y - x : y;
31         if (y != n) printf("%d\n", a[fixY]); else printf("%d\n", a[fixY + 1]);
32     }
33     return 0;
34 }
View Code

 

转载于:https://www.cnblogs.com/JHSeng/p/11304703.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值