题意:给你一个整数n,和m个非负数,求1到n-1中有多少个数能被m个数中其中一个数整除
可能1-n中的一个数能同时被多个数整除(奇加偶减)
用队里数组和dfs都可以实现
dfs代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,cnt;
int a[11];
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
void dfs(int pre,int len,int lcm,int num)
{
if(num==len)
{
cnt+=(n-1)/lcm;
return ;
}
for(int i=pre;i<=m;i++)
{
int GCD;
if(lcm<a[i])
GCD=gcd(a[i],lcm);
else
GCD=gcd(lcm,a[i]);
lcm=a[i]*(lcm/GCD);
dfs(i+1,len+1,lcm,num);
lcm=lcm/a[i]*GCD;
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int ans=0,t=0;
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
if(x!=0) a[++t]=x;
}
m=t;
for(int i=1;i<=m;i++)
{
cnt=0;
dfs(1,0,1,i);
if(i%2)
ans+=cnt;
else ans-=cnt;
}
printf("%d\n",ans);
}
return 0;
}
队列数组
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int a[21];
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int solve(int m,int n)
{
int t=0,que[111111];
que[t++]=-1;
for(int i=0;i<m;i++)
{
int k=t;
for(int j=0;j<k;j++)
{
int r=abs(que[j]);
int temp=a[i]/gcd(a[i],r)*que[j];
que[t++]=temp*(-1);// 这里不一定是质因数,所以判断一次
}
}
int sum=0;
for(int i=1;i<t;i++)
sum+=n/que[i];
return sum;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
int t=0;
for(int i=1;i<=m;i++)
{
if(a[i])
a[t++]=a[i];
}
printf("%d\n",solve(t,n-1));
}
return 0;
}