2014 Multi-University Training Contest 2 部分题目解题报告

官方题解:http://blog.sina.com.cn/s/blog_6bddecdc0102uyex.html

这场被许多人吐槽难度太大。难度大,比赛时就只能硬啃,出不来的题也得硬出。不能以此为退缩的理由。

 

HDOJ 4873 ZCC Loves Intersection

读题很困难。理解题意以后其实还好,很容易想到只要研究某两条线段的变换的两维的情况即可。公式不方便贴出来,反正过程和官方题解差不多。然后就是高精度比较麻烦,代码是学长敲的java,我还不会java。。

变量名有点逗

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

 

 

HDOJ 4876 ZCC loves cards

也是一个坑,大概意思就是因为数据随机产生所以我们就可以用搜索啦。比较有用的剪枝就是枚举出所选数以后,先放宽条件,不考虑顺序,是否能生成L到已知ANS+1的数,不能就不用展开求这些数的序列了。然后我比较挫地写了3个dfs,其中只有第一个枚举所选数有必要,生成序列可以用next_permutation(好像是这个),暴力o(2^k)判断所选数,可以不用递归,用两个for即可(外层循环枚举已经生成的数,初始只有一个0,之后以2倍的速度增长,内层循环k个数依次和已经生成的数异或,并作为新生成的数加在末尾)

  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);
View Code

 

 

HDOJ 4882 ZCC Loves Codefires

很常见的贪心。先考虑相邻的元素的顺序,继而推出整体的顺序即可。

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

 

转载于:https://www.cnblogs.com/james47/p/3871854.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值