2016香港-思维&数学-Playing with Numbers

https://vjudge.net/problem/Kattis-playingwithnumbers
给定一群数。用 x y表示(这个数的值为2^x*3^y)
然后让你输出 m-1行。
第一行 没有gcd操作,有m-1个lcm操作
第二行 1个gcd操作,m-2个lcm操作
。。第m-1行 m-1个gcd操作 0个lcm操作
输出每行(对应情况)的 可能取的最大值,最小值。
仍用 x y 这种形式表示。


这道题我感觉难点在于 比较2^x1*3^y1 和2^x2*3^y2的大小。
但是我们知道了这个,,竟然没有做出来。。。。
本题中 数据范围很大。
并且发现 都是2^x*3^y的格式,这种格式保证了一点。
那就是 lcm两个数,就是两个数 再x和y的幂项上取最大。
而gcd呢,就是取最小。。(mdzz现在看起来感觉在情理之中)
当第一行时 ,只能等到最大值。
第二行, 最大值可以得到,最小值就是 最小的整体
中间情况,多可以得到最大值,最小值。
倒数第二行 ,最大值就是 整体最大(留这个整体最大的和其他lcm)
最小值 是可以得到的。
最后一行 ,只能得到最小值。
注意 当m==3时,m-1和2发生了重合。
当前情况下,和M-1行情况相同。 假设 x 为2的幂最大的数。
y为3的幂最大得数。 z为整体最大
那么 无疑 lcm(z,gcd(x,y)) 比gcd(lcm(x,y),z)要好。

#include <bits/stdc++.h>
using namespace std;
const int maxn=6e4+100;
struct Node{
    int x,y;
}node[maxn];
bool cmp2(Node a, Node b)
{
    return ( log(2) * a.x + log(3) * a.y) < (log(2) * b.x + log(3) * b.y);
}
int main()
{    int m;
     while(~scanf("%d",&m)){
          for(int i=1;i<=m;i++){
               scanf("%d%d",&node[i].x,&node[i].y);
          }
          sort(node+1,node+m+1,cmp2);
          int max1=-1;
          int max2=-1;
          int min1=1e7;
          int min2=1e7;
          for(int i=1;i<=m;i++){
              max1=max(max1,node[i].x);
              min1=min(min1,node[i].x);
              max2=max(max2,node[i].y);
              min2=min(min2,node[i].y);
          }
          if(m==1){
             printf("%d %d %d %d\n",max1,max2,max1,max2);
          }
          else if(m==2){
              printf("%d %d %d %d\n",max1,max2,max1,max2);
             printf("%d %d %d %d\n",min1,min2,min1,min2);
          }
          else{
               for(int i=1;i<=m;i++){
                  if(i==1)
                    printf("%d %d %d %d\n",max1,max2,max1,max2);
                   else if(i==m-1)
                    printf("%d %d %d %d\n",node[m].x,node[m].y,min1,min2);
                  else if(i==2)
                    printf("%d %d %d %d\n",max1,max2,node[1].x,node[1].y);
                  else if(i==m)
                    printf("%d %d %d %d\n",min1,min2,min1,min2);
                  else
                    printf("%d %d %d %d\n",max1,max2,min1,min2);
               }
          }
     }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值