官方题解:http://blog.sina.com.cn/s/blog_6bddecdc0102uyex.html
这场被许多人吐槽难度太大。难度大,比赛时就只能硬啃,出不来的题也得硬出。不能以此为退缩的理由。
HDOJ 4873 ZCC Loves Intersection
读题很困难。理解题意以后其实还好,很容易想到只要研究某两条线段的变换的两维的情况即可。公式不方便贴出来,反正过程和官方题解差不多。然后就是高精度比较麻烦,代码是学长敲的java,我还不会java。。
变量名有点逗
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 import java.io.*;
2 import java.math.*;
3 import java.util.*;
4
5 public class Main{
6 public static void main(String [] args){
7 Scanner cin;
8 cin = new Scanner(System.in);
9 Integer d, n;
10 BigInteger son, mom, gcd;
11 while (cin.hasNextInt()){
12 n = cin.nextInt();
13 d = cin.nextInt();
14 mom = BigInteger.valueOf(n).pow(d).multiply(BigInteger.valueOf(9));
15 son = BigInteger.valueOf(n+4).pow(2).multiply(BigInteger.valueOf(d).multiply(BigInteger.valueOf(d-1)).divide(BigInteger.valueOf(2)));
16 gcd = mom.gcd(son);
17 mom = mom.divide(gcd);
18 son = son.divide(gcd);
19 if (mom.equals(BigInteger.ONE)) System.out.println(son);
20 else System.out.println(son+"/"+mom);
21 }
22 cin.close();
23 }
24 }
HDOJ 4876 ZCC loves cards
也是一个坑,大概意思就是因为数据随机产生所以我们就可以用搜索啦。比较有用的剪枝就是枚举出所选数以后,先放宽条件,不考虑顺序,是否能生成L到已知ANS+1的数,不能就不用展开求这些数的序列了。然后我比较挫地写了3个dfs,其中只有第一个枚举所选数有必要,生成序列可以用next_permutation(好像是这个),暴力o(2^k)判断所选数,可以不用递归,用两个for即可(外层循环枚举已经生成的数,初始只有一个0,之后以2倍的速度增长,内层循环k个数依次和已经生成的数异或,并作为新生成的数加在末尾)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5
6 bool flag;
7 int n, k, l;
8 int need, ans;
9 bool vis[130], use[30];
10 int a[30], b[30], c[30];
11 int cal()
12 {
13 memset(vis, false, sizeof(vis));
14 int tmp;
15 for (int i = 0; i < k; i++){
16 tmp = 0;
17 for (int j = 0; j < k; j++){
18 int pos = i + j;
19 if (pos > k-1) pos -= k;
20 tmp ^= c[pos];
21 vis[tmp] = true;
22 }
23 }
24 if (!vis[l]) return 0;
25 for (int i = l+1; i <= 200; i++)
26 if (!vis[i]) return i - 1;
27 }
28 bool check(int dep, int pre)
29 {
30 //printf("dep %d pre %d\n", dep, pre);
31 /*
32 if (pre == need) return true;
33 if (dep == k) return false;
34 bool flag = check(dep+1, pre^b[dep]);
35 if (!flag) flag = check(dep+1, pre);
36 return flag;
37 */
38 if (dep == k){
39 for (int i = l; i <= 200; i++)
40 if (!vis[i]){
41 flag = (i-1) >= need;
42 return 0;
43 }
44 }
45 vis[pre] = true;
46 vis[pre^b[dep]] = true;
47 check(dep+1, pre);
48 check(dep+1, pre^b[dep]);
49 return 0;
50 }
51 void dfs2(int dep)
52 {
53 if (dep == k){
54 int tmp = cal();
55 // printf("%d\n", tmp);
56 if (tmp > ans){
57 ans = tmp;
58 need = tmp + 1;
59 }
60 return;
61 }
62 for (int i = 0; i < k; i++)
63 if (!use[i]){
64 use[i] = true;
65 c[dep] = b[i];
66 dfs2(dep+1);
67 use[i] = false;
68 }
69 }
70 void dfs(int dep, int pos)
71 {
72 if (dep == k){
73 memset(vis, 0, sizeof(vis));
74 flag = false;
75 check(0, 0);
76 if (flag){
77 /*
78 puts("in!\n b[]: ");
79 for (int i = 0; i < k; i++)
80 printf("%d ", b[i]);
81 puts("");
82 */
83 dfs2(0);
84 }
85 return;
86 }
87 for (int i = pos+1; i < n && n-i >= k-dep; i++){
88 //for (int i = pos + 1; i < n && n-1-i >= k-(dep+1); i++){
89 //for (int i = pos+1; i < n; i++){
90 b[dep] = a[i];
91 dfs(dep+1, i);
92 }
93 }
94 int main()
95 {
96 memset(use, false, sizeof(use));
97 while(scanf("%d%d%d", &n, &k, &l) != EOF)
98 {
99 for (int i = 0; i < n; i++)
100 scanf("%d", a + i);
101 sort(a, a+n);
102 ans = 0, need = l;
103 dfs(0, -1);
104 printf("%d\n", ans);
105 }
106 return 0;
107 }
108 r(i);
HDOJ 4882 ZCC Loves Codefires
很常见的贪心。先考虑相邻的元素的顺序,继而推出整体的顺序即可。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #include<cstdlib>
7 #include<set>
8 #include<map>
9 #include<queue>
10 #include<ctime>
11 #include<string>
12 using namespace std;
13
14 struct node{
15 int e, k;
16 }a[101000];
17 int n, sum[101000];
18 bool cmp(node a, node b)
19 {
20 return a.e * b.k < b.e * a.k;
21 }
22 int main()
23 {
24 while(scanf("%d", &n) != EOF)
25 {
26 for (int i = 0; i < n; i++)
27 scanf("%d", &a[i].e);
28 for (int i = 0; i < n; i++)
29 scanf("%d", &a[i].k);
30 sort(a, a+n, cmp);
31 sum[0] = 0;
32 for (int i = 0; i < n; i++)
33 sum[i] = sum[i-1] + a[i].e;
34 long long ans = 0;
35 for (int i = 0; i < n; i++)
36 ans += (long long)(sum[i]) * a[i].k;
37 printf("%I64d\n", ans);
38 //printf("%lld\n", ans);
39 }
40 return 0;
41 }