Codeforces Round #319 (Div. 2)

题目地址

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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值