zoukankan      html  css  js  c++  java
  • 7.3.5 The Balance

    The Balance

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 72 Accepted Submission(s): 50

    Problem Description
    Now you are asked to measure a dose of medicine with a balance and a number of weights. Certainly it is not always achievable. So you should find out the qualities which cannot be measured from the range [1,S]. S is the total quality of all the weights.
     

    Input
    The input consists of multiple test cases, and each case begins with a single positive integer N (1<=N<=100) on a line by itself indicating the number of weights you have. Followed by N integers Ai (1<=i<=N), indicating the quality of each weight where 1<=Ai<=100.
     

    Output

                For each input set, you should first print a line specifying the number of qualities which cannot be measured. Then print another line which consists all the irrealizable qualities if the number is not zero.
     

    Sample Input
    3
    1 2 4
    3
    9 2 1
     

    Sample Output
    0
    2
    4 5

    意思是,用a[1],a[2]..,a[n]重量的砝码,每个砝码只能用一次,问在[1,a[1]+a[2]+..+a[n]]的范围内,有多少重量是无法通过天平称量的。

    很明显,天平的话,如果是两个值 9 4 既可以称出13也可以称出5(9-4); (62ms)

    只需在母函数里面加一句话,

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <string>
     6 #include <cstdlib>
     7 using namespace std;
     8 
     9 const int maxn=10210;
    10 int cnt,n,sum,k;
    11 int c1[maxn],c2[maxn],a[maxn],ans[maxn];
    12 
    13 void close()
    14 {
    15 exit(0);
    16 }
    17 
    18 
    19 void init()
    20 {
    21     while(scanf("%d",&n)!=EOF)
    22     {
    23         sum=0;
    24         for (int i=1;i<=n;i++)
    25             scanf("%d",&a[i]),sum+=a[i];
    26         memset(c1,0,sizeof(c1));
    27         memset(c2,0,sizeof(c2));
    28         c1[0]=1;c1[a[1]]=1;
    29         for (int i=2;i<=n;i++)
    30         {
    31             for (int j=0;j<=sum;j++)
    32             {
    33                 if (c1[j]==0) continue;
    34                 k=0;
    35                 c2[j+k]+=c1[j];
    36                 c2[abs(j-k)]+=c1[j];
    37                 k=a[i];
    38                 c2[j+k]+=c1[j];
    39                 c2[abs(j-k)]+=c1[j];
    40             }
    41             for (int j=0;j<=sum;j++)
    42                 c1[j]=c2[j],c2[j]=0;
    43         }
    44         cnt=0;
    45         for (int i=1;i<=sum;i++)
    46             if (c1[i]==0)
    47             {
    48                 cnt++;
    49                 ans[cnt]=i;
    50             }
    51         printf("%d
    ",cnt);
    52         for (int i=1;i<=cnt;i++)
    53             if (i==cnt)
    54                 printf("%d
    ",ans[i]);
    55             else
    56                 printf("%d ",ans[i]);
    57     }
    58 }
    59 
    60 int main ()
    61 {
    62     init();
    63     close();
    64     return 0;
    65 }

    另外一种方法就是DP啦,我居然还跑的最快 31ms

    枚举每一个砝码,然后找出[1,sum]里面那些值已经可以取到了,然后前后更新即可

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <string>
     6 #include <cstdlib>
     7 using namespace std;
     8 
     9 const int maxn=10210;
    10 int cnt,n,sum,k;
    11 int a[maxn],ans[maxn],b[maxn];
    12 bool f[maxn];
    13 
    14 void close()
    15 {
    16 exit(0);
    17 }
    18 
    19 
    20 void init()
    21 {
    22     while(scanf("%d",&n)!=EOF)
    23     {
    24         sum=0;
    25         for (int i=1;i<=n;i++)
    26             scanf("%d",&a[i]),sum+=a[i];
    27         memset(f,false,sizeof(f));
    28         for (int i=1;i<=n;i++)
    29         {
    30             cnt=0;
    31             for (int j=sum;j>=0;j--)
    32                 if (f[j])
    33                 {
    34                     cnt++;
    35                     b[cnt]=j;
    36                 }
    37             for (int j=1;j<=cnt;j++)
    38             {
    39                 f[b[j]+a[i]]=true;
    40                 f[abs(b[j]-a[i])]=true;
    41             }
    42             f[a[i]]=true;
    43         }
    44         cnt=0;
    45         for (int i=1;i<=sum;i++)
    46             if (not f[i])
    47             {
    48                 cnt++;
    49                 ans[cnt]=i;
    50             }
    51         printf("%d
    ",cnt);
    52         for (int i=1;i<=cnt;i++)
    53             if (i==cnt)
    54                 printf("%d
    ",ans[i]);
    55             else
    56                 printf("%d ",ans[i]);
    57     }
    58 }
    59 
    60 int main ()
    61 {
    62     init();
    63     close();
    64     return 0;
    65 }
  • 相关阅读:
    U盘PE系统下安装WIN2003和WINXP的方法(非GHOST版)
    自己做U盘急救杀毒
    Windows Server 2003 SP2 企业版 ISO 下载 629M
    解决开机关机慢问题
    一般处理程序
    [转]iframe自适应高度详解(希望对大家有用)非常经典,非同凡响
    ie6下position fixed的失效bug
    php文件上传MAX_FILE_SIZE不起作用的问题
    IE6测试网页显示空白页面
    自己写的面向过程php验证码
  • 原文地址:https://www.cnblogs.com/cssystem/p/3212348.html
Copyright © 2011-2022 走看看