CF1034A:
题意:
给 n n n 个数,要求删除尽可能少的数使得剩下的数的 gcd i = 1 k a i \gcd_{i=1}^ka_i gcdi=1kai 比原来大,无解输出 − 1 -1 −1
题解:
首先显然让所有
a
i
←
a
i
g
c
d
i
=
1
k
a
i
a_i \gets \frac{a_i}{gcd_{i=1}^ka_i}
ai←gcdi=1kaiai 不会影响答案
然后问题就变成了删除最少的数使得
g
c
d
i
=
1
k
a
i
≠
1
gcd_{i=1}^ka_i \neq 1
gcdi=1kai=1
然后就变成了找一个质因数,使得数组中含有它的数最多
然后就没有然后了\
代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
const int maxm = 1.5e7 + 10,maxn = 3e5 + 10;
int n, pn, a[maxn],p[maxm],m[maxm];
bool book[maxm];
int cnt[maxm];
int gcd(int x,int y){return y == 0 ? x : gcd(y,x % y);}
int main(){
scanf("%d",&n);
scanf("%d",&a[1]);
int mingcd = a[1],Max = -1;
for(int i = 2;i <= n;i++){
scanf("%d",&a[i]);
mingcd = gcd(mingcd,a[i]);
}
for(int i = 1;i <= n;i++){
a[i] /= mingcd;
Max = max(Max,a[i]);
cnt[a[i]]++;
}
for(int i = 2;i <= Max;i++){
if(!book[i]){
p[++pn] = i;
}
for(int j = 1;i * p[j] <= Max && j <= pn;j++){
book[i * p[j]] = 1;
if(i % p[j] == 0)break;
}
}
int ans = 0;
for(int i = 1;i <= pn;i++){
int res = 0;
for(int j = 1;j * p[i] <= Max;j++)res += cnt[j * p[i]];
ans = max(ans,res);
}
if(ans == 0){
puts("-1");
return 0;
}
printf("%d\n",n - ans);
return 0;
}
CF1034B:
题意:
给一个 n × m n \times m n×m 的棋盘,每次允许填入一对曼哈顿距离恰好为 3 3 3 的棋子,问最多可以填入多少个棋子。
题解:
毒瘤恶心题
首先手玩下就可以发现以下几种格子是可以完全填下的
1
×
6
1 \times 6
1×6
1 | 2 | 3 | 1 | 2 | 3 |
---|
2 × 4 2 \times 4 2×4
1 | 2 | 3 | 4 |
---|---|---|---|
3 | 4 | 1 | 2 |
2 × 5 2 \times 5 2×5
1 | 2 | 5 | 1 | 3 |
---|---|---|---|---|
5 | 4 | 3 | 2 | 4 |
3 × 4 3 \times 4 3×4
1 | 4 | 2 | 3 |
---|---|---|---|
6 | 3 | 5 | 4 |
5 | 1 | 6 | 2 |
然后就是肥肠恶心的分类讨论\
-
n
=
1
∣
∣
m
=
1
n=1 ||m=1
n=1∣∣m=1
这个时候不难发现只能填入 1 × 6 1 \times 6 1×6 的格子,剩下的格子如果多于 3 3 3 个就可以再填入 $ (m\space mod \space 6 - 3) \times 2 $个格子 -
n
=
2
∣
∣
m
=
2
n=2||m=2
n=2∣∣m=2
不妨假设 n = 2 n=2 n=2 (反之交换 n n n 和 m m m),不难发现当 ∃ a , b , c ∈ Z , m = 4 a + 5 b + 6 c \exist a,b,c \in Z,m=4a+5b+6c ∃a,b,c∈Z,m=4a+5b+6c 时可以填满,而显然仅当 m = 2 o r 3 o r 7 m=2\space or\space 3\space or\space 7 m=2 or 3 or 7 时无解,答案分别为 0 , 4 , 12 0,4,12 0,4,12,其他情况都是 n × m n\times m n×m -
n
≥
3
n≥3
n≥3 且 $ n≥3$ 且 (
2
∣
n
2 | n
2∣n 或
2
∣
m
2 | m
2∣m)
不妨设 2 ∣ n 2|n 2∣n- m = 3 m=3 m=3 : 完全可以用一个 3 × 4 3 \times 4 3×4 的矩形和三个 1 × 6 1\times 6 1×6 的矩形填满
- m = 7 m=7 m=7 : 在上面的基础上在追加两个 2 × 4 2 \times 4 2×4 的矩形和四个 1 × 6 1 \times 6 1×6填满
- 故此时答案为 n × m n\times m n×m
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, m;
signed main(){
scanf("%lld%lld",&n,&m);
int ans = 0;
if(n == 1){ans = (m / 6) * 6 + (max(m % 6 - 3,0LL) * 2);}
else if(m == 1){ans = (n / 6) * 6 + (max(n % 6 - 3,0LL) * 2);}
else if(n == 2){ans = (m == 2 ? 0 : (m == 3 ? 4 : (m == 7 ? 12 : (n * m))));}
else if(m == 2){ans = (n == 2 ? 0 : (n == 3 ? 4 : (n == 7 ? 12 : (n * m))));}
else if(n >= 3 && m >= 3 && (n % 2 == 0 || m % 2 == 0)){ans = n * m;}
else ans = n * m - 1;
printf("%lld\n",ans);
return 0;
}