众所周知,我是好人!所以不会出太难的题,题意很简单
给你n个数,问你1000000000(含1e9)以内有多少个正整数不是这n个数任意一个的倍数
最后友情提供解题代码(我真是太好人了)
void solve(int p[], int n)
{
int ans = 0;
for (int i = 1; i <= 1e9; i++)
{
int fl = 0;
for (int j = 0; j < n; j++)
{
if (i % p[j] == 0)
{
fl = 1;
break;
}
}
if (fl == 0)ans++;
}
printf("%d\n", ans);
}
Input
第1行是一个整数T,表示共T组数据。 接下来是T组数据,每组数据第1行是正整数n(n<=50),接下来是n个正整数(小于等于1000),任意两数用1个空格隔开,最前数前面与最后数后面无空格
Output
输出T行,对应T组数据。(T<=10) 每行输出这样的正整数有多少个
Sample Input
342 3 5 71213854 101 143 282 538 922 946 286 681 977 892 656 907
Sample Output
228571428500000000968701719
HINT
提示:数据是随机生成的,尔等尽可随意乱搞
原理 是 容斥 ,所以用dfs 和 最小公倍数来算,不过在这之前先把给的数中 倍数之间的数给划掉,还有出现 数字1的情况 。
倍数若大于1e9 就剪枝。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int maxn = 1e9;
int vis[55];
int num[55];
int a[55];
int m = 0;
LL ans = 0;
LL p;
int n;
LL gcd(LL x, LL y) {
return y ? gcd(y, x%y) : x;
}
void dfs(LL i, LL q, LL k) {
if (q > maxn)
return;
for (; i < m; i++)
{
p = a[i] / gcd(a[i], q)*q;
ans += k * (maxn / p);
dfs(i + 1, p, -k);
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
m = 0;
memset(vis, 0, sizeof(vis));
bool one = false;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &num[i]);
if (num[i] == 0) {
vis[num[i]] = true;
}
if (num[i] == 1)
{
one = true;
}
}
if (one) {
printf("0\n");
continue;
}
sort(num, num + n);
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++) {
if (vis[j] == 0&& vis[i] == 0 && num[j] % num[i] == 0)
vis[j] = 1;
}
if (vis[i]==0)
a[m++] = num[i];
}
ans = 0;
dfs(0, 1, 1);
printf("%lld\n", maxn - ans);
}
return 0;
}