zoukankan      html  css  js  c++  java
  • 2015 Multi-University Training Contest 6 solutions BY ZJU(部分解题报告)

    官方解题报告:http://bestcoder.hdu.edu.cn/blog/2015-multi-university-training-contest-6-solutions-by-zju/

    表示很难看。。。。orz

    1003题      链接:http://acm.hdu.edu.cn/showproblem.php?pid=5355

    Cake

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 1138    Accepted Submission(s): 152
    Special Judge


    Problem Description
    There are m soda and today is their birthday. The 1-st soda has prepared n cakes with size 1,2,,n. Now 1-st soda wants to divide the cakes into m parts so that the total size of each part is equal. 

    Note that you cannot divide a whole cake into small pieces that is each cake must be complete in the m parts. Each cake must belong to exact one of m parts.
     


     

    Input
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    The first contains two integers n and (1n105,2m10), the number of cakes and the number of soda.
    It is guaranteed that the total number of soda in the input doesn’t exceed 1000000. The number of test cases in the input doesn’t exceed 1000.
     


     

    Output
    For each test case, output "YES" (without the quotes) if it is possible, otherwise output "NO" in the first line.

    If it is possible, then output m lines denoting the m parts. The first number si of i-th line is the number of cakes in i-th part. Then si numbers follow denoting the size of cakes in i-th part. If there are multiple solutions, print any of them.
     


     

    Sample Input
    4 1 2 5 3 5 2 9 3
     


     

    Sample Output
    NO YES 1 5 2 1 4 2 2 3 NO YES 3 1 5 9 3 2 6 7 3 3 4 8
     


     

    Source
     

    题意:n块蛋糕(大小1--n)分给m个人,要求每个人得到蛋糕大小总和相等

    
    
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int MAXN = 500000 + 10;
     5 int ret[10][MAXN];
     6 int vis[100], a[100];
     7 int tot, tar;
     8 
     9 bool dfs(int dep, int now, int u, int c)
    10 {
    11     if (now == 0)
    12     {
    13         int k = 0;
    14         while (vis[k] != -1) ++ k;
    15         vis[k] = c;
    16         if (dfs(dep + 1, a[k], k + 1, c)) return true;
    17         vis[k] = -1;
    18         return false;
    19     }
    20     if (now == tar)
    21     {
    22         if (dep == tot) return true;
    23         else return dfs(dep, 0, 0, c + 1);
    24     }
    25     for (int i = u; i < tot; ++ i)
    26     {
    27         if (vis[i] == -1 && now + a[i] <= tar)
    28         {
    29             vis[i] = c;
    30             if (dfs(dep + 1, now + a[i], i + 1, c)) return true;
    31             vis[i] = -1;
    32         }
    33     }
    34     return false;
    35 }
    36 
    37 int main()
    38 {
    39     int T;
    40     scanf("%d", &T);
    41     for (int cas = 1; cas <= T; ++ cas)
    42     {
    43         int n, k;
    44         scanf("%d%d", &n, &k);
    45         //fprintf(stderr, "%d %d
    ", n, k);
    46         LL sum = (LL)n * (n + 1) / 2;
    47         if (sum % k == 0 && n >= k * 2 - 1)
    48         {
    49             while (n >= 40)
    50             {
    51                 for (int i = 0; i < k; ++ i) ret[i][++ ret[i][0]] = n - i;
    52                 for (int i = 0; i < k; ++ i) ret[i][++ ret[i][0]] = n - k * 2 + i + 1;
    53                 n -= k * 2;
    54             }
    55             tot = n;
    56             tar = n * (n + 1) / 2 / k;
    57             for (int i = 0; i < tot; ++ i) a[i] = tot - i;
    58             for (int i = 0; i < tot; ++ i) vis[i] = -1;
    59             dfs(0, 0, 0, 0);
    60             for (int i = 0; i < tot; ++ i)
    61             {
    62                 ret[vis[i]][++ ret[vis[i]][0]] = a[i];
    63             }
    64             for (int i = 0; i < k; ++ i)
    65             {
    66                 printf("%d ", ret[i][0]);
    67                 for (int j = 1; j <= ret[i][0]; ++ j) printf(" %d", ret[i][j]);
    68                 puts("");
    69             }
    70         }
    71         else puts("NO");
    72     }
    73     return 0;
    74 }


     

    1006题          链接:http://acm.hdu.edu.cn/showproblem.php?pid=5358

    First One

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 757    Accepted Submission(s): 230


    Problem Description
    soda has an integer array a1,a2,,an. Let S(i,j) be the sum of ai,ai+1,,aj. Now soda wants to know the value below:
    i=1nj=in(log2S(i,j)+1)×(i+j)

    Note: In this problem, you can consider log20 as 0.
     


     

    Input
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    The first line contains an integer (1n105), the number of integers in the array.
    The next line contains n integers a1,a2,,an (0ai105).
     


     

    Output
    For each test case, output the value.
     


     

    Sample Input
    1
    2
    1 1
     


     

    Sample Output
    12
     


     

    Source
     


     

    题意:求

    思路:利用S(i,j)单调性,     log2(S(i,j))+1= k =2^(k-1)<= S(i,j)<2^k

    考虑枚举log(sum(i,j)+1的值,记为k,然后统计(i+j)的和即可。

    对于每一个k,找到所有满足2^(k-1)<=sum(i,j)<=2^k-1的(i+j),

    k<=2*log2(10^5)<34

    转载请注明出处:寻找&星空の孩子 

     

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<algorithm>
     4 #define LL long long
     5 using namespace std;
     6 LL num[100005];
     7 LL sum[100005];
     8 int main()
     9 {
    10     int T;
    11     scanf("%d",&T);
    12     while(T--)
    13     {
    14         LL n;
    15         scanf("%lld",&n);
    16         num[0]=sum[0]=0;
    17         for(int i=1; i<=n; i++)
    18         {
    19             scanf("%lld",&num[i]);
    20             sum[i]=sum[i-1]+num[i];
    21         }
    22         LL ans=0;
    23         for(LL k=1; k<=34; k++)
    24         {
    25             LL l=1,r=0;//注意r的初始值在l的左边;因为存在1个值的情况!
    26             LL KL=1LL<<(k-1);
    27             if(k==1) KL--;
    28             LL KR=1LL<<(k);
    29             for(LL i=1; i<=n; i++)
    30             {
    31                 l=max(i,l);//区间左边界
    32                 while(l<=n&&sum[l]-sum[i-1]<KL) l++;//确定左边界
    33                 r=max(l-1,r);//区间右边界,注意r在l前的时候从l-1开始
    34                 while(r+1<=n&&sum[r+1]-sum[i-1]>=KL&&sum[r+1]-sum[i-1]<KR) r++;//确定区间右边界
    35                 if(r<l) continue;
    36                 ans+=k*((i+l)+(i+r))*(r-l+1)/2;
    37             }
    38         }
    39         printf("%lld
    ",ans);
    40     }
    41     return 0;
    42 }
    
    
    
    
    
    

    1008题         链接:http://acm.hdu.edu.cn/showproblem.php?pid=5360

    Hiking

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 544    Accepted Submission(s): 290
    Special Judge


    Problem Description
    There are n soda conveniently labeled by 1,2,,n. beta, their best friends, wants to invite some soda to go hiking. The i-th soda will go hiking if the total number of soda that go hiking except him is no less than li and no larger than ri. beta will follow the rules below to invite soda one by one:
    1. he selects a soda not invited before;
    2. he tells soda the number of soda who agree to go hiking by now;
    3. soda will agree or disagree according to the number he hears.

    Note: beta will always tell the truth and soda will agree if and only if the number he hears is no less than li and no larger than ri, otherwise he will disagree. Once soda agrees to go hiking he will not regret even if the final total number fails to meet some soda's will.

    Help beta design an invitation order that the number of soda who agree to go hiking is maximum.
     


     

    Input
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    The first contains an integer (1n105), the number of soda. The second line constains n integers l1,l2,,ln. The third line constains n integers r1,r2,,rn(0lirin)
    It is guaranteed that the total number of soda in the input doesn't exceed 1000000. The number of test cases in the input doesn't exceed 600.
     


     

    Output
    For each test case, output the maximum number of soda. Then in the second line output a permutation of 1,2,,n denoting the invitation order. If there are multiple solutions, print any of them.
     


     

    Sample Input
    4 8 4 1 3 2 2 1 0 3 5 3 6 4 2 1 7 6 8 3 3 2 0 5 0 3 6 4 5 2 7 7 6 7 6 8 2 2 3 3 3 0 0 2 7 4 3 6 3 2 2 5 8 5 6 5 3 3 1 2 4 6 7 7 6 5 4 3 5
     


     

    Sample Output
    7 1 7 6 5 2 4 3 8 8 4 6 3 1 2 5 8 7 7 3 6 7 1 5 2 8 4 0 1 2 3 4 5 6 7 8
     


     

    Source
     


     

    题意:问邀请的顺序,使得最终去的人最多,每个人有一个区间[l,r]的人数要求

    分析:用优先队列维护,按照r从小到大;不是很难注意细节。

      1 #include<stdio.h>
      2 #include<queue>
      3 #include<algorithm>
      4 #include<string.h>
      5 using namespace std;
      6 const int N = 100005;
      7 struct nnn
      8 {
      9     int l,r,id;
     10 }node[N];
     11 struct NNNN
     12 {
     13     int r,id;
     14     friend bool operator<(NNNN aa,NNNN bb)
     15     {
     16         return aa.r>bb.r;
     17     }
     18 };
     19 
     20 priority_queue<NNNN>q;
     21 bool cmp1(nnn aa, nnn bb)
     22 {
     23     return aa.l<bb.l;
     24 }
     25 int id[N];
     26 bool vist[N];
     27 int main()
     28 {
     29     int T,n,ans;
     30     NNNN now;
     31     scanf("%d",&T);
     32     while(T--)
     33     {
     34         scanf("%d",&n);
     35         ans=0;
     36 
     37         /*for(int i=1; i<=n; i++)
     38             printf("%d ",i);
     39             printf("=id
    
    ");*/
     40         for(int i=0; i<n; i++)
     41         {
     42             scanf("%d",&node[i].l);
     43             node[i].id=i+1;
     44         }
     45         for(int i=0; i<n; i++)
     46             scanf("%d",&node[i].r);
     47         sort(node,node+n,cmp1);
     48         memset(vist,0,sizeof(vist));
     49         int i=0;
     50         while(i<n)
     51         {
     52             bool ff=0;
     53             while(i<n&&ans>=node[i].l&&ans<=node[i].r)
     54             {
     55                 now.r=node[i].r;
     56                 now.id=node[i].id;
     57                 q.push(now);
     58                 //printf("in = %d
    ",now.id);
     59                 i++;
     60                 ff=1;
     61             }
     62             if(ff)i--;
     63             while(!q.empty())
     64             {
     65                 now=q.top(); q.pop();
     66                 if(now.r<ans)continue;
     67                 //printf("out = %d
    ",now.id);
     68                 ans++;
     69                 id[ans]=now.id;
     70                 vist[now.id]=1;
     71                 if(node[i+1].l<=ans)
     72                     break;
     73             }
     74             i++;
     75         }
     76         while(!q.empty())
     77         {
     78             now=q.top(); q.pop();
     79             if(now.r<ans)continue;
     80             //printf("out = %d
    ",now.id);
     81             ans++;
     82             id[ans]=now.id;
     83             vist[now.id]=1;
     84         }
     85 
     86         bool fff=0;
     87         printf("%d
    ",ans);
     88         for( i=1; i<=ans; i++)
     89         if(i>1)
     90             printf(" %d",id[i]);
     91         else if(i==1)
     92             printf("%d",id[i]);
     93         if(ans)fff=1;
     94         for( i=1; i<=n; i++)
     95             if(vist[i]==0&&fff)
     96                 printf(" %d",i);
     97             else if(vist[i]==0)
     98                 printf("%d",i),fff=1;
     99         printf("
    ");
    100     }
    101 }



    1011题      链接:http://acm.hdu.edu.cn/showproblem.php?pid=5363

    Key Set

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 420    Accepted Submission(s): 275


    Problem Description
    soda has a set S with n integers {1,2,,n}. A set is called key set if the sum of integers in the set is an even number. He wants to know how many nonempty subsets of S are key set.
     


     

    Input
    There are multiple test cases. The first line of input contains an integer (1T105), indicating the number of test cases. For each test case:

    The first line contains an integer (1n109), the number of integers in the set.
     


     

    Output
    For each test case, output the number of key sets modulo 1000000007.
     


     

    Sample Input
    4 1 2 3 4
     


     

    Sample Output
    0 1 3 7
     


     

    Source
     


    
    
    
     1 #include<stdio.h>
     2 #define LL long long
     3 #define mod 1000000007
     4 LL ppow(LL a,LL b)
     5 {
     6     LL c=1;
     7     while(b)
     8     {
     9         if(b&1) c=c*a%mod;
    10         b>>=1;
    11         a=a*a%mod;
    12     }
    13     return c;
    14 }
    15 int main()
    16 {
    17     int T;
    18     LL n;
    19     scanf("%d",&T);
    20     while(T--)
    21     {
    22         scanf("%lld",&n);
    23         printf("%lld
    ",ppow(2,n-1)-1);
    24     }
    25     return 0;
    26 }


     

  • 相关阅读:
    Codeforces 754A Lesha and array splitting (搜索)
    浅入分析Linux
    MakeFile基本使用
    Mac 安装YCM
    Homebrew 配置
    虚拟机复制操作CentOS6导致eth0转为eth0以至于网络服务启动失败的解决方案
    Kickstart安装
    Linux编译安装MySQL
    Python源码读后小结
    编译原理小结
  • 原文地址:https://www.cnblogs.com/yuyixingkong/p/4710671.html
Copyright © 2011-2022 走看看