A. Multiplication Table
题目大意:按照一定的规则给方格定长为n的方格填数,求方格中给定的X有多少个
解题思路:模拟求一个数的倍数是否为给定的X,注意边界条件
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <list>
#include <set>
using namespace std;
int main()
{
int n,x,ans;
while(~scanf("%d%d",&n,&x))
{
ans = 0;
for(int i = 1; i <= n; i++)
{
if(!(x%i) && x/i <= n) ans++;
}
printf("%d\n",ans);
}
return 0;
}
B. Modulo Sum
题目大意:给出有n个数的数组及m,问你能否在这个数组中找一个非空的子序列,然后使得它们的和能被m整除
解题思路:当n>=m时,根据鸽巢原理,若n个数除以m余数都不相同,则一定有个余数为0,若n个数除以m余数至少有2个相同,则有sl%m = sr%m --->(sr-sl)%m=0.所以一定有子序列和能被m整除;
当n<m时,相当于01背包。dp[i]表示是否存在子序列和除以m的余数为i,此题即需找dp[0]是否存在
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+100;
const int maxm = 1e3+100;
int a[maxn],dp[maxm],tmp[maxm];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
if(n >= m)
{
puts("YES");
continue;
}
memset(dp,0,sizeof(dp));
for(int i = 0; i < n; i++)
{
if(dp[0]) break;
for(int j = 0; j < m; j++)
if(dp[j])
tmp[(j+a[i])%m] = 1;
tmp[a[i]%m] = 1;
for(int j = 0; j < m; j++)
dp[j] = tmp[j];
}
if(dp[0]) puts("YES");
else puts("NO");
}
return 0;
}
C. Vasya and Petya's Game
题目大意:A给出一个数x,B每次猜一个y,A回答B,x是否可以被y整除,求出要猜的最小次数和需要猜的数。
解题思路:素数筛处理出所有素数,枚举每个素数p,可以知道如果p^k<=n,则p^k一定需要选,根据这个原则求出所有要猜的数。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3+100;
int ans[maxn],prime[maxn];
void isPrime()
{
memset(prime,0,sizeof(prime));
prime[1] = 1;
for(int i = 2; i <= maxn; i++)
{
for(int j = 2*i; j <= maxn; j += i)
{
prime[j] = 1;
}
}
}
int main()
{
int n;
isPrime();
while(~scanf("%d",&n))
{
int cnt = 0;
int tmp;
for(int i = 2; i <= n; i++)
{
if(!prime[i])
{
tmp = i;
ans[cnt++] = tmp;
while(tmp*i <= n)
{
tmp *= i;
ans[cnt++] = tmp;
}
}
}
printf("%d\n",cnt);
for(int i = 0; i < cnt; i++)
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}