zoukankan      html  css  js  c++  java
  • BestCode#38 B

    题目链接:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=577&pid=1002

    题目大意:在n个数里面任选两个x,y找出里面gcd(x,y)最大的gcd值。

    解析:由于n的范围是2到10w,所以暴力枚举肯定超时。

    解法一:对于输入的n 个数依次求出他们的因子,将因子个数记录在ant[]数组内。我们容易知道,如果一个因子的个数超过2 的话,那么这个因子必为公因子。所以我们只需要寻找这些公因子里面最大的那个就可以了。详细代码如下:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #define max(x,y) x>y?x:y
     5 using namespace std;
     6 
     7 int ant[1000006];
     8 int a[1000006];
     9 int main()
    10 {
    11     int t;
    12     scanf ("%d",&t);
    13     for(int i=1;i<=t;i++)
    14     {
    15         int n,maxp=1;
    16         memset(ant,0,sizeof(ant));
    17         scanf ("%d",&n);
    18         for(int j=0;j<n;j++)
    19         {
    20             scanf ("%d",&a[j]);
    21             for(int k=1;k<=a[j];k++)//计算n个数的因子,因子个数存放在ant[]数组内
    22             {
    23                 if(a[j]%k==0)
    24                     ant[k]++;
    25             }
    26             maxp=max(maxp,a[j]);
    27         }
    28         int ans=1;
    29         for(int j=1;j<=maxp;j++)
    30         {
    31             if(ant[j]>=2)//寻找公因子找到最大的那个公因子
    32                 ans=max(ans,j);
    33         }
    34         printf("Case #%d: %d
    ",i,ans);
    35     }
    36     return 0;
    37 }

    解法二:首先maxp是n个数里的最大数。那么这个最大公因子必然在1~maxp之间。那么我们可以直接在maxp~1之间枚举每个数k,判断在n个数里面是否有2个或者更多的k的倍数。一旦找到这样的数k,那么可以断定k就是答案。直接跳出循环。不需要执行以后的循环了,节约了大部分时间。代码如下:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 int ant[1000006],a[1000006];
     7 int main()
     8 {
     9     int t;
    10     scanf ("%d",&t);
    11     for(int i=1;i<=t;i++)
    12     {
    13         memset(ant,0,sizeof(ant));
    14         int maxp=1,n,j,k;
    15         scanf ("%d",&n);
    16         for(j=1;j<=n;j++)
    17         {
    18             scanf ("%d",&a[j]);
    19             maxp=max(maxp,a[j]);
    20             ant[a[j]]++;
    21         }
    22         int flag=0;
    23         for(j=maxp;j>=1;j--)//从maxp~1枚举每个数
    24         {
    25             int num=0;
    26             for(k=j;k<=maxp;k=k+j)
    27             {
    28                 if(ant[k])//寻找k的倍数的个数。
    29                     num+=ant[k];
    30                 if(num>1)//一旦找到了这样的数j,他的倍数个数大于1,则直接跳出循环。
    31                 {
    32                     flag=1;
    33                     printf("Case #%d: %d
    ",i,j);
    34                     break;
    35                 }
    36             }
    37             if(flag)
    38                 break;
    39         }
    40     }
    41     return 0;
    42 }

    结论:当暴力不能解决问题的时候需要转个弯,从问题的深层次来思考,或者想出一种巧妙的办法,理解问题,拆开问题,才能不断打开思路。

  • 相关阅读:
    同node上,两个pod通过svc访问不通
    Prometheus基于service自动添加监控
    systemd 服务管理编写
    kubernetes 控制器详解【持续完善中】
    tcpdump抓包工具
    Zabbix日志监控插件
    Spring WebFlux之HttpHandler的探索
    知秋源码解读分享系列
    Spring Framework 5.0.0.M3中文文档 翻译记录 Part I. Spring框架概览1-2.2
    Spring Framework 5.0.0.M3中文文档 翻译记录 introduction
  • 原文地址:https://www.cnblogs.com/bei-insomia/p/4438501.html
Copyright © 2011-2022 走看看