Codeforces Round #511 (Div. 1)

A - Enlarge GCD

题意:给n个数,那么他们有gcd,去掉最多n-1个数使得他们的gcd变大。求去掉最少的数。

题解:首先如果所有数都相等,那么无解。否则一定有解:最多去掉只剩下最大的那个。gcd是没有影响的,可以直接除掉(注意gcd可以用0来初始化,0和x的gcd都等于x)。然后除去gcd之后每个数有他独特的几种因子,把不含这种因子的数都去掉就可以把这种因子释放出来。暴力sqrt分解会T掉,线性筛/埃筛预处理出每个数的最小质因子(甚至不需要预处理出他的幂,反正除一除也是log级别的)就把复杂度降低到质因子的最大个数(当一直除时,大概27左右)或者质因子的种类(当预处理出每个数含有的最小质因子的幂时,不超过8个),比sqrt的大概4000要快100倍。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAXN = 1e7 + 5e6;
int p[970704 + 5], ptop;
int pm[MAXN + 5], pk[MAXN + 5];

void sieve() {
    int n = MAXN;
    pm[1] = 1;
    pk[1] = 1;
    for(int i = 2; i <= n; i++) {
        if(!pm[i]) {
            p[++ptop] = i;
            pm[i] = i;
            pk[i] = i;
        }
        for(int j = 1; j <= ptop; j++) {
            int t = i * p[j];
            if(t > n)
                break;
            pm[t] = p[j];
            if(i % p[j]) {
                pk[t] = pk[p[j]];
            } else {
                pk[t] = pk[i] * p[j];
                break;
            }
        }
        //printf("i=%d pm=%d pk=%d\n", i, pm[i], pk[i]);
    }
    //printf("ptop=%d\n",ptop);
    /*for(int i=1;i<=ptop;++i)
        printf("%d:%d\n",i,p[i]);*/
}

int a[300005];
int ans[MAXN + 5];

void test_case() {
    int n, cnt1 = 0;
    scanf("%d", &n);
    int gcd = 0;
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
        gcd = __gcd(gcd, a[i]);
    }
    for(int i = 1; i <= n; ++i) {
        a[i] /= gcd;
        while(a[i] > 1) {
            ans[pm[a[i]]]++;
            a[i] /= pk[a[i]];
        }
    }
    int minans = n;
    for(int i = 1; i <= MAXN; ++i)
        minans = min(minans, n - ans[i]);
    printf("%d\n", minans == n ? -1 : minans);
}

B - Little C Loves 3 II

题意:给n*m的棋盘,每次放曼哈顿距离为3的一对棋子,求最多放多少个棋子。

题解:已知假如行是6的倍数或者列是6的倍数就直接可以放满。可以大胆猜测要模到6以内求解(但不能够同时模到6以内,比如2 8,这个假如区域赛遇到就要拜托队友手动打表找,然后和小数据比对了,毕竟大数据按常理是很容易放满的)。

余1的话,那就直接贪心放就可以了。

余2的情况,只有2*1,2*2,2*3,2*7是不能放满的。(放满可以构造证明,但是放不满怎么证明呢?)

余4的情况,注意到4*2和4*3可以放满,所以4*x当x>=2时都可以放满。

余3和余5的情况,多放几个发现是两个都是奇数的时候就是-1,否则可以放满,可能是因为>=3的都很好调整。

总之这道题出得很不好,正式比赛出了要被喷。

原文地址:https://www.cnblogs.com/KisekiPurin2019/p/11969900.html

时间: 2024-08-30 13:09:38

Codeforces Round #511 (Div. 1)的相关文章

Codeforces Round #511 (Div. 2)-C - Enlarge GCD (素数筛)

传送门:http://codeforces.com/contest/1047/problem/C 题意: 给定n个数,问最少要去掉几个数,使得剩下的数gcd 大于原来n个数的gcd值. 思路: 自己一开始想把每个数的因子都找出来,找到这些因子中出现次数最多且因子大于n个数的最大公约数的,(n - 次数 )就是答案.但是复杂度是1e9,差那么一点. 自己还是对素数筛理解的不够深.这道题可以枚举素数x,对于每个x,找到所有(a[i]/gcd(all)) 是x倍数的个数,就是一个次数.找这个次数的过程

Codeforces Round #511 (Div. 2)

又到了摸鱼的时候了23333 A. Little C Loves 3 I 题意:给一个数,分解为不被3整除的3个数 题解:构造,如果这个数被3整除,就构造为1,1,n-2:否则构造为1,2,n-3 1 class Solution(object): 2 def run(self): 3 n = int(input()) 4 if n % 3 == 0: 5 print(1, 1, n - 2) 6 else: 7 print(1, 2, n - 3) 8 9 if __name__ == '__

Codeforces Round #511 (Div. 2) C. Enlarge GCD

题目链接 题目就是找每个数的最小素因子,然后递归除,本来没啥问题,结果今天又学习了个新坑点. 我交了题后,疯狂CE,我以为爆内存,结果是,我对全局数组赋值, 如果直接赋值,会直接在exe内产生内存,否则只会在运行时才分配内存. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1e7 + 5e6 + 10; 5 6 //线性素数筛 7 int prime[2000000],num_prime = 0;

A. Little C Loves 3 I Codeforces Round #511 (Div. 2) 【数学】

题目: Little C loves number ?3? very much. He loves all things about it. Now he has a positive integer nn. He wants to split nn into 3 positive integers a,b,ca,b,c, such that a+b+c=na+b+c=n and none of the 3 integers is a multiple of 3. Help him to fin

C. Enlarge GCD Codeforces Round #511 (Div. 2)【数学】

题目: Mr. F has nn positive integers, a1,a2,-,an. He thinks the greatest common divisor of these integers is too small. So he wants to enlarge it by removing some of the integers. But this problem is too simple for him, so he does not want to do it by

Codeforces Round 511 Div.1 B

Description Given a \(n \times m\) chessboard, every time put two chessman with Manhattan distance 3 between them. Calculate the maximum number of chessmen you can put on it. \(n, m \le 10^9\). Solution All possible pairs of position is a biparite gr

Codeforces Round #511 (Div. 2) C. Enlarge GCD (质因数)

题目 题意: 给你n个数a[1]...a[n],可以得到这n个数的最大公约数, 现在要求你在n个数中 尽量少删除数,使得被删之后的数组a的最大公约数比原来的大. 如果要删的数小于n,就输出要删的数的个数, 否则输出 -1 . 思路: 设原来的最大公约数为 g, 然后a[1]...a[n]都除以g ,得到的新的a[1]...a[n],此时它们的最大公约数一定是1 . 设除以g之后的数组a为: 1    2    3     6      8   10  则它们的质因数分别是:  1    2   

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿