zoukankan      html  css  js  c++  java
  • HDU 3784 继续xxx定律 & HDU 2578 Dating with girls(1)

    HDU 3784 继续xxx定律

    HDU 2578 Dating with girls(1)

    做3748之前要先做xxx定律  对于一个数n,如果是偶数,就把n砍掉一半;如果是奇数,把n变成 3*n+ 1后砍掉一半,直到该数变为1为止。

    当n为3时,我们在验证xxx定律的过程中会得到一个序列,3,5,8,4,2,1,将3称为关键数,5,8,4,2称为覆盖数。现在输入n个数字a[i],根据关键数与覆盖数的理论,我们只需要验证其中部分数就可以确定所有数满足xxx定律,输出输入的n个数中的关键数。如果其中有多个关键数的话按照其输入顺序的逆序输出。

    所以只需把n个数都当做关键数,一一标记a[i]的覆盖数,最后在这数列中找到未被标记的,逆序输出。

    15 ms

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 using namespace std;
     5 int main()
     6 {
     7   int a[1005],b[10005],i,n,x,y,c[130000]; //a为原数列,b为未被标记的数列,c为标记,记得c要开很大,因为要(x*3+1)/2可能很大
     8   while(~scanf("%d",&n)&&n)
     9   {
    10     memset(c,0,sizeof(c));   //清零
    11     for(i=1;i<=n;i++)
    12       scanf("%d",&a[i]);
    13     for(i=1;i<=n;i++)
    14     {
    15       x=a[i];
    16       if(!c[x])   //未被标记,若已被标记那么x的覆盖数已全被标记
    17         while(x!=1)
    18         {
    19           if(x%2==0)
    20           {
    21             x/=2;
    22             c[x]=1;
    23           }
    24           else
    25           {
    26             x=(3*x+1)/2;
    27             c[x]=1;
    28           }
    29         }
    30     }
    31     y=0;
    32     for(i=1;i<=n;i++)
    33       if(c[a[i]]==0)   //未被标记
    34         b[++y]=a[i];
    35     for(i=y;i>=2;i--)  //逆序输出
    36       printf("%d ",b[i]);
    37     printf("%d
    ",b[1]);
    38   }
    39   return 0;
    40 }

    第二题 2578

    大意是:给出n个数,满足x属于n,y属于n,x+y=k的方案数。      PS;1+3和3+1算两种,2+2只算一种

    刚开始想用母函数做.....后来发现k<2^31,数组开不了这么大T^T

    后来是周XX说用二分= =,想想也是......

    然后各种改,错了6次!!!!     406MS

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 int main()
     7 {
     8     int T,n,k,i,a[100005],l,r,sum,x,mid,y;
     9     scanf("%d",&T);
    10     while(T--)
    11     {
    12         sum=0;
    13         y=0;
    14         scanf("%d%d",&n,&k);
    15         for(i=1;i<=n;i++)
    16         {
    17             scanf("%d",&a[i]);
    18             if(k%2==0&&a[i]==k/2)   //如果存在k/2这个数,则方法数+1
    19                 y=1;
    20         }
    21         a[0]=-1;
    22         sort(a+1,a+n+1);    //排序
    23         for(i=1;i<=n;i++)
    24         if(a[i]<(k+1)/2 && a[i]!=a[i-1])      //先1,3;3,1只算一种,不要重复算     ①
    25         { 
    26             x=k-a[i];    //找y
    27             l=0; 
    28             r=n+1;     //②
    29             mid=(l+r)/2;
    30             while(r-l>1)      //③
    31             {
    32                 mid=(l+r)/2;
    33                 if(a[mid]>x)
    34                     r=mid;
    35                 if(a[mid]<x)
    36                     l=mid;
    37                 if(a[mid]==x)
    38                     break;
    39             }
    40             if(a[mid]==x)
    41                 sum++;
    42         }
    43         sum=sum*2+y;   //sum*2+是否有x=y这种情况
    44         printf("%d
    ",sum);
    45     }
    46     return 0;
    47 }

    做的时候有几个易错的地方:  ①②③

    还有一组很难过得数据:

    3 4

    1 2 3

    两道这样的题做了那么久.......╭(╯^╰)╮

  • 相关阅读:
    预览PDF【reactpdf】插件的使用(二)
    多叉merkletree的实现
    中国优秀的架构师是不是出现了严重断层?
    工程师的思维转变
    QCore/Library说明文档
    QParserGenerator代码分析二(A fix&An example)
    山寨STL实现之list
    山寨STL实现笔记
    山寨STL实现之内存池V2
    词法分析器1(正则表达式到εNFA的转换)
  • 原文地址:https://www.cnblogs.com/riddle/p/3382338.html
Copyright © 2011-2022 走看看