zoukankan      html  css  js  c++  java
  • codeforces 980D Perfect Groups

    题意:

    有这样一个问题,给出一个数组,把里面的数字分组,使得每一个组里面的数两两相乘都是完全平方数。

    问最少可以分成的组数k是多少。

    现在一个人有一个数组,他想知道这个数组的连续子数组中,使得上面的问题答案分别为1到n的数组有多少个。

    第一个样例

    2

    5 5

    子数组有[5],[5],[5 5]三个,这三个组最少可以分别分为1 1 1组,使得每个组的任意两个数相乘都是平方数。

    思路:

    感谢js帮本智障debug。

    首先对于一个不为0的数,如果把它的所有完全平方数的因子去掉,那么是不会影响结果的。

    所以首先把每个数的完全平方数因子去掉,注意负数的处理

    然后剩下的数都可以表示为一个或者多个质数的乘积,那么两两相乘为平方数只有一种情况,就是两个数字相等。

    所以问题转化为了求一个数组的连续子数组中有多少个不相等的数字,那么这个子数组就可以最少分为几个组。

    离散化统计每个区间内的不同的数字就行了,用set或者map会T,不知道为什么。。。复杂度O(n^2)。

    注意有0的时候,除非每个元素都是0,否则0可以加入任何一个分组,得特殊处理一下,具体看代码。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <set>
     5 #include <math.h>
     6 using namespace std;
     7 const int N = 500100;
     8 int a[N];
     9 int b[N];
    10 int c[N];
    11 bool vis[N];
    12 int mabs(int x)
    13 {
    14     return x >= 0 ? x : -x;
    15 }
    16 int main()
    17 {
    18     int n;
    19     int cnt = 0;
    20     scanf("%d",&n);
    21     for (int i = 0;i < n;i++)
    22     {
    23         scanf("%d",&a[i]);
    24         if (a[i] != 0) cnt++;
    25     }
    26     if (cnt == 0)
    27     {
    28         printf("%d ",n * (n + 1) / 2);
    29         for (int i = 1;i < n;i++) printf("0 ");
    30     }
    31     else
    32     {
    33         for (int i = 0;i < n;i++)
    34         {
    35             if (a[i] == 0) continue;
    36             int tmp = mabs(a[i]);
    37             for (int j = 2;j * j <= tmp;j++)
    38             {
    39                 int t = j * j;
    40                 while (a[i] % t == 0)
    41                 {
    42                     a[i] /= t;
    43                 }
    44                 //if (a[i] < t) break;加了这个就wa,卡了一晚上,考虑的应该是绝对值的情况
    45             }
    46         }
    47         for (int i = 0;i < n;i++) c[i] = a[i];
    48         sort(c,c+n);
    49         int js = unique(c,c+n) - c;
    50         for (int i = 0;i < n;i++)
    51         {
    52             if (a[i] == 0) continue;
    53             int p = lower_bound(c,c+js,a[i]) - c + 1;
    54             a[i] = p;
    55         }
    56         for (int i = 0;i < n;i++)
    57         {
    58             memset(vis,0,sizeof(vis));
    59             int num = 0;
    60             for (int j = i;j < n;j++)
    61             {
    62                 if (!vis[a[j]] && a[j] != 0)
    63                 {
    64                     num++;
    65                     vis[a[j]] = 1;
    66                 }
    67                 int tt = max(num,1);
    68                 b[tt]++;
    69             }
    70         }
    71         for (int i = 1;i <= n;i++)
    72         {
    73             printf("%d ",b[i]);
    74         }
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    Less与Sass
    JQuery基础
    JS中DOM以及BOM
    JS函数入门
    JS入门
    响应式布局和弹性布局,移动开发常用技巧
    CSS基础1
    H5入门
    error C2143: syntax error : missing ';' before 'type'
    Windows系统下nodejs安装及配置
  • 原文地址:https://www.cnblogs.com/kickit/p/9018561.html
Copyright © 2011-2022 走看看