zoukankan      html  css  js  c++  java
  • 2012 MultiUniversity Training Contest 3

    1001  HDU4320  Arcane Numbers 1

    GCD 0MS 无压力 

    代码: 

    View Code 
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #define LL __int64
     5 using namespace std;
     6 LL gcd(LL a,LL b)
     7 {
     8     return b==0?a:gcd(b,a%b);
     9 }
    10 int main()
    11 {
    12     LL a,b,c;
    13     int t,k=0;
    14     scanf("%d",&t);
    15     while(t--)
    16     {
    17         k++;
    18         scanf("%I64d%I64d",&a,&b);
    19         c=gcd(a,b);
    20         while(c>1)
    21         {
    22             a/=c;
    23             c=gcd(a,b);
    24         }
    25         printf("Case #%d: ",k);
    26         if(a==1)
    27             puts("YES");
    28         else
    29             puts("NO");
    30     }
    31     return 0;
    32 }
    33


    1005  HDU4324  Trangle LOVE

    人人上有个神人说  直接计算每个点出度,没有两个出度相等的情况下为NO,其他为YES,就过了。果然如此。。。。

    代码: 


    View Code 
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 int main()
     7 {
     8     int a[2001];
     9     int i,j,k=0,t,n,flag;
    10     char b;
    11     scanf("%d",&t);
    12     while(t--)
    13     {
    14         memset(a,0,sizeof(a));
    15         flag=0;
    16         k++;
    17         scanf("%d",&n);
    18         for(i=0;i<n;i++)
    19         {
    20             getchar();
    21             for(j=0;j<n;j++)
    22             {
    23                 b=getchar();
    24                 if(b=='1')
    25                 {
    26                     a[i]++;
    27                 }
    28             }
    29         }
    30         sort(a,a+n);
    31         for(i=0;i<n-1;i++)
    32         {
    33             if(a[i]==a[i+1])
    34             {
    35                 flag=1;
    36                 break;
    37             }
    38         }
    39         printf("Case #%d: ",k);
    40         if(flag)
    41             puts("Yes");
    42         else
    43             puts("No");
    44     }
    45     return 0;
    46 }
    47



    1006  HDU4325  Flowers

    比较裸的区间更新的线段树

    代码:

    View Code 
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 #define lson l,m,rt<<1
     6 #define rson m+1,r,rt<<1|1
     7 #define LL __int64
     8 const int N=100002;
     9 LL add[N<<2];
    10 LL sum[N<<2];
    11 void pushup(LL rt)
    12 {
    13     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    14 }
    15 void pushdown(LL rt,LL m)
    16 {
    17     if(add[rt]) 
    18     {
    19         add[rt<<1]+=add[rt];
    20         add[rt<<1|1]+=add[rt];
    21         sum[rt<<1]+=add[rt]*(m-(m>>1));
    22         sum[rt<<1|1]+=add[rt]*(m>>1);
    23         add[rt]=0;
    24     }
    25 }
    26 void build(LL l,LL r,LL rt) 
    27 {
    28     add[rt]=0;
    29     if(l==r) 
    30     {
    31         sum[rt]=0;
    32         return ;
    33     }
    34     int m=(l+r)>>1;
    35     build(lson);
    36     build(rson);
    37     pushup(rt);
    38 }
    39 void update(LL L,LL R,LL c,LL l,LL r,LL rt) 
    40 {
    41     if(L<=l&&r<=R) 
    42     {
    43         add[rt]+=c;
    44         sum[rt]+=(LL)c*(r-l+1);
    45         return ;
    46     }
    47     pushdown(rt,r-l+1);
    48     LL m=(l+r)>>1;
    49     if(L<=m) 
    50         update(L,R,c,lson);
    51     if(m<R) 
    52         update(L,R,c,rson);
    53     pushup(rt);
    54 }
    55 LL query(LL L,LL R,LL l,LL r,LL rt) 
    56 {
    57     if(L<=l&&r<=R) 
    58     {
    59         return sum[rt];
    60     }
    61     pushdown(rt,r-l+1);
    62     LL m=(l+r)>>1;
    63     LL ret=0;
    64     if(L<=m) 
    65         ret+=query(L,R,lson);
    66     if(m<R) 
    67         ret+=query(L,R,rson);
    68     return ret;
    69 }
    70 int main() 
    71 {
    72     int t,k=0;
    73     scanf("%d",&t);
    74     while(t--)
    75     {
    76         k++;
    77         int i,j;
    78         __int64 a,b,c,d;
    79         scanf("%I64d%I64d",&a,&b);
    80         build(1,N,1);
    81         for(i=0;i<a;i++)
    82         {
    83             scanf("%I64d%I64d",&c,&d);
    84             update(c,d,1,1,N,1);
    85         }
    86         printf("Case #%d:\n",k);
    87         for(j=0;j<b;j++)
    88         {
    89             scanf("%I64d",&c);
    90             printf("%I64d\n",query(c,c,1,N,1));
    91         }
    92     }
    93     return 0;
    94 }
    95

    附:

    官方题解:

    1001
    检查A中的质因子 是否都在 B中被包含。
    1002
    按位统计计算,如果枚举 那么复杂度就是 64 * N
    第一条
    当统计第K位的时候 可以注意到 第 B+T*A  和 B+(T+2^(K+1))*A 位是相同的
    那么 第K位的时候 只需要统计2^K 次就可以了 
    第二条
    当统计第K位的时候 可以注意到 连续的 (2^K)/A都是连续的0 或者连续的1 所以可以考虑直接连续记录(2^K)/A个结果。                
    那么 第K位的时候 只需要统计N / ((2^K)/A)次就可以了                 
    综合 第一条 第二条  那么 第K位的时候 只需要统计 2^K/((2^K)/A) 复杂度 变为O(A)              
    总复杂度为64*A
     
    1003

    【题目大意】

    有N颗糖果和M个小孩,老师现在要把这N颗糖分给这M个小孩。每个小孩i对每颗糖j都有一个偏爱度Aij,如果他喜欢这颗糖,Aij = k,否则Aij = 1。小孩i觉得高兴当且仅当ΣCij×Aij >= Bi,j=1,2,…,N,若他分得了糖j,Cij = 1,否则Cij = 0。问能否合理分配这N颗糖,使得每个小孩都觉得高兴。
    【建模方法】
    (最大费用最大流)
             本题有一个突破点就是:他喜欢这颗糖,Aij = k,否则Aij = 1,关键在于如果他不喜欢这个糖分给他一样可以获得1点的欢乐值。也就是说如果之前分配了的糖给了小孩一定的欢乐值,不够bi,可以直接用随意的糖去填满。
    首先我们要求欢喜值>=bi,是否可以认为当我获得欢喜值为bi后,多余欢喜值对这个结果的满足是没有贡献的。也就是说,你可以用一个容量来控制分配糖对小孩欢喜值的控制,让获得欢喜值最多为bi。如果不够,最后用一些1的糖来填满。
    而这个容量就是bi/c,获取贡献为k,bi%c(>1)的也是可以用一个能让这个小孩欢喜的糖来贡献,但是其费用只为bi%c。
    对于小孩来说,最大费用最大流后,糖分配的贡献值为最大费用,剩余糖就是(n-最大流),然后用这些糖去填不满的,只要满足总和大于Σbj。就可以分配了。
    具体建模方案1:
    (s,i,1,0);
    (i,j,1,0);
    (j,t,bj/k,k);
    If(bj%k>1)
    (j,t,1,bj%k)
    Ans = 费用 + N – 最大流 >= Σbj  则满足要求
    具体建模方案2:
    (s,I,1,0)  
    (I,j,1,0)
    (j,t,bj/k,k-1);
    If(bj%k>1)
    (j,t,1,bj%k-1);
    Ans = 费用+N  >= Σbj  则满足要求

    当k = 2时候,可以不用费用流,最大流即可。

    一种最直观的想法就是每颗糖i作为一个点并连边(s, i, ?),每个小孩j作为一个点并连边(j, t, Bj)。若小孩j喜欢糖果i则连边(i, j, 2),否则连边(i, j, 1),然后求一次最大流看是否等于ΣBj。但是问题也很明显,我们还没有给与源点关联的边确定容量。实际上我们无法确定它们的容量,因为最大流无法实现这样一种控制:一个点有若干条出边,容量不尽相同,现在要求经过该点的流可以任选一条出边流走,且一旦选定之后就只能从这条边流而不能再进入其他的出边。因此我们无法确定与源关联的边的容量,因为经过每颗糖i的流无法在出边容量有1又有2的情况下作出正确的选择。
    那么是否就没有办法了呢?虽然流无法在容量有1又有2的情况下作出正确的选择,但却可以在容量有1又有0的情况下最自然地作出正确的选择,流过去就表示选择了那条出边,且因为容量为1,不会再有流进入其他的出边。那么此题的构图方法也就出来了:每颗糖i作为一个点并连边(s, i, 1),每个小孩j作为一个点并连边(j, t, floor(Bj/2)),若小孩j喜欢糖果i则连边(i, j, 1),否则连边(i, j, 0)或者干脆不连边,效果一样。设最大流为ans,若ans+N >= ΣBj则可以满足要求。为什么?因为每颗糖迟早都要分给某个小孩,它一定会为总权值贡献1,只不过如果它分给了喜欢它的小孩就再额外贡献1。现在我只考虑这额外的1单位贡献究竟能送出去多少,最后加上基值N并与ΣBj比较即可。
     

    1004

    这道题求两个字符串编辑距离的部分用动态规划就可以了,如果不加任何优化,总的复杂度是1500*1000*10*10,时间给了1s,如果写的效率比较高,有可能可以水过。
    标程的用到了一个叫做BK-Tree的数据结构优化一下,其实原理很简单,可以参考wiki http://en.wikipedia.org/wiki/BK-tree和matrix67的blog http://www.matrix67.com/blog/archives/333
     
    1005
    题目描述:
    2000个点的有向图,保证任意两点间仅有一条有向边。
    解题报告:
    增量算法,充分利用“任意两点间仅有一条有向边”的性质。
    假设前面已经加入了N个点,现在来了第N+1个点。
    那么一定能将N个点分成left和right两部分,使得N+1号点到left有边,right到N+1号点右边(因为任意两点间都有边),那么,如果left的任意一个点l到right任意一个点r有边的话,那么就有答案N+1->l->r->N+1这样一个长度为3的环。
    那么每次加入N+1号点后,用O(N)的复杂度求出左边的数量leftnum,右边的数量rightnum,left的出度和leftout,left的入度和leftin。
    如果left没有一条到right的边,则一定满足:
    leftin = leftout + leftnum * rightnum(left和right任意两点右边,如果没有左到右的,那么leftnum*rightnum条边都是右到左的)
    那么,如果leftin != leftout + leftnum * rightnum,则暴力枚举左点,右点即可得到答案。
    总体复杂度O(n^2)
     
    附加一份其他人的解题报告
    lengxiang解题报告:
    我稍微的看了下出题人的解题报告,没咋看懂。稍微有所启发。写了一个不一样的代码,数据同样通过。
    归结为1个条件,任何两人都有边,要么出要么入。
    对于有向三元环,我们知道找到:A->B->C->A ,B->C->A->B ,C->A->B->C 是一样的,这给0(n^2)的算法提供了基础。
            对于每次枚举i,我们在(0~i-1)的范围看下有多少个i指向的点(剩下的就是指向i的点),同时算下i指向的点的出度和。就可以知道这些 i指向的点 指向 指向i的点(剩下的点)的数目,如果 
            num * (num - 1) / 2 < sumout 那么就是被指向的点有指出去了,这样就形成了3元环。
            否则,剩下的就是更新下出度即可,继续执行下一个节点。
     
    1006
    这个题就是比较裸的区间更新,单点查询的线段树。一开始需要把要查询的点和花开的时间和花谢的时间一起离散化了,这样查询的时候就方便多了。
     

    1007

    本题题意很简单,给出n个人每次4人进行比赛其他人等待,胜者继续,负者排到最后,连续或得m次胜利的人成为最终的赢家,求第k个人最终获得胜利的概率是多少?
    对于这题,我们首先确立一个这样的模型: x1先赢了i局,正在于x2,x3,x4赌斗,后面依次有x5,x6,……,xn等待。用P[i][j]表示x1先赢了i局的情况下,当前的xj获胜的概率。
    不难得到以下的一些式子:

     i < m

    P[i][j] = P[i + 1][j] * 1/4 + P[1][n - 2] * 3/4                                                 j = 1
    P[i + 1][n - 2] * 1/4 + P[1][1] * 1/4 + P[1][n - 1] * 2/4                                 j = 2
    P[i + 1][n - 1] * 1/4 + P[1][1] * 1/4 + P[1][n - 1] * 1/4 + P[1][n] * 1/4          j = 3
    P[i + 1][n] * 1/4 + P[1][1] * 1/4 + P[1][n] * 2/4                                           j = 4
    P[i + 1][j - 3] * 1/4 + P[1][j - 3] * 3/4                                                         j>=4
     

    i = m

    P[i][j] = 1                                                                                                   j = 1
    0                                                                                                               j != 1
     

    于是我们得到了一个未知数为n*m个的方程组。用高斯消元法解之即可。

    值得注意的是,以上思想并不难想到,但是普通的高斯消元法会由于舍入误差使得结果出现很大的偏差,这里我们采用的是分数形式的高斯消元的解法。

     

    1008

    首先利用旋转卡壳计算出每个点的凸包,由于密度公式非常特殊,则利用公式微积分即可算得每个点落到上面的概率。具体详见代码
     
    1009
    本题主要考察DP状态转移以及数据结构的使用。相邻块不能相同的最长周长的正方形,直接用O(1)转移的二维dp可以实现,g[i][j]表示右下角选为(i,j)的周长最长正方形,根据图像特性,g[i][j] = min( g[i-1][j] , g[i][j-1] ) or g[i][j] = min( g[i-1][j] , g[i][j-1] ) + 1,是否需要加1取决于对于块的颜色与map(i,j)上的颜色是否相同。
    对于周长最长的同色矩形,首先O(n)枚举矩形的下底,然后从左至右O(m)依次枚举相应左右边界的最大值,枚举工作使用队列提速,询问过程涉及到区间更新区间查询的功能,使用线段树优化查询效率,复杂度O(n * m * lg(n)); 从左至右O(m)枚举时,也可以使用栈来保存每一列连续颜色的高度,同时可以求周长的最大值,复杂度(n * m)。
     

    1010

    本题是一道简单的模拟题,关键点是看懂题目绕口的定义,然后按照题目所给的公式求解即可。实现过程可以使用map来判断检索出的url是否为相关文件,使用istringstream处理字符串操作。具体如何实现都行,总之本题考察读题和基本字符串处理。
     

    1011

    搜索+剪枝               
    如果遇到已经100%的情况就直接break             
    一开始可以不去考虑不会补充新的棋子的情况 如果有100%的情况 那也可以直接break了。
  • 相关阅读:
    JS转义 escape()、encodeURI()、encodeURIComponent()区别详解
    PHP解决搜索时在URL地址栏输入中文字符搜索结果出现乱码
    CMSPRESS-PHP无限级分类2
    CMSPRESS-PHP无限级分类
    HTML5-CSS3-JavaScript(3)
    HTML5-CSS3-JavaScript(2)
    HTML5-CSS3-JavaScript(1)
    CSS3-Hover 效果 展示
    JAVA Socket地址绑定
    JAVA Socket无参构造方法的使用
  • 原文地址:https://www.cnblogs.com/pony1993/p/2617253.html
Copyright © 2011-2022 走看看