AtCoder Beginner Contest 233(A~D)题解

AtCoder Beginner Contest 233题解

文章目录

  • AtCoder Beginner Contest 233题解
    • A - 10yen Stamp
    • B - A Revers
    • C - Product
    • D - Count Interval

A - 10yen Stamp

【题目链接】A - 10yen Stamp (atcoder.jp)

题意:当前数每次可以加10,问至少要加几次才能寄信

  • x > y:说明足够寄送了
  • x < y:不能送,则加10,知道x > y为止,计数即可。

【代码实现】

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;



int main() 
{
    int x, y;
    cin >> x >> y;

    if(x >= y) cout << 0;
    else 
    {
        int ans = 0;
        while(x < y)
        {

            x += 10;
            ans ++;
        }
        cout << ans;
    }
    
    return 0;
}


B - A Revers

【题目链接】B - A Reverse (atcoder.jp)

题意:将字符串s在[l,r]的字串翻转后,输出s

知识点:字符串模拟

【代码实现】

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 1e5 + 10;
char s[N];

int main() 
{

    int l, r;
    scanf("%d%d", &l, &r);
    scanf("%s", s + 1);
    int len = strlen(s + 1);

    //双指针实现翻转
    int i = l, j = r;
    while(i < j) swap(s[i ++], s[j --]);
    
    printf("%s", s + 1);
    
    return 0;
}


C - Product

【题目链接】C - Product (atcoder.jp)

题意:有n个包,每个包里有若干带数字的球,让你每个包里面选一个球使得数字乘积为x,最后让你求满足等于x的方案数。

注:

  • 数据的范围
  • 剪枝

知识点:DFS

【代码实现】

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 1e5 + 10;

int n, res = 0;
LL target;
vector<LL> a[N];// 二维数组

void dfs(int u, LL val)//选择到了第几个背包 现在背包的重量是多少
{
    if(u == n)
    {
        if(val == target) res ++;
        return ;
    }
    for(int j = 0; j < a[u].size(); j ++)// 用vector做的二维数组,每一层调用.size(),即可得到当前层的背包的个数
    {
        if(a[u][j] * val > target) continue;// 剪枝
        dfs(u + 1, val * a[u][j]);
    }
}

int main() 
{
    scanf("%d%lld", &n, &target);
    for(int i = 0; i < n; i ++)
    {
        int cnt;
        scanf("%d", &cnt);
        for(int j = 0; j < cnt; j ++)
        {
            LL value;
            scanf("%lld", &value);
            a[i].push_back(value);
        }
    }
    dfs(0, 1);
    printf("%d", res);
    return 0;
}


D - Count Interval

【题目链接】D - Count Interval (atcoder.jp)

题意:统计s[r]-s[l - 1] == k出现的次数

思路:如果枚举区间的话,时间复杂度会爆炸,统计s[r]-s[l - 1] == k等价于统计s[r]-k == s[l - 1]。然后对于每个r只需要求下 s[r]-k的个数,也就是s[l-1]的个数。s[l-1]也是个前缀和,所以循环的时候顺便把前缀和个数自增 。(枚举右端点求s[r]-k == s[l - 1]的次数,只不过我们在计数前缀和时同时预处理出来了s[l-1]的值,因为它也是个前缀和的值!)

知识点:前缀和 + 哈希表

【代码实现】

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 2e5 + 10;
LL s[N];

int main() 
{

    LL n, k, res = 0;
    scanf("%lld%lld", &n, &k);

    unordered_map<LL, LL> hasp;
    for(int i = 1; i <= n; i ++)
    {
        scanf("%lld", &s[i]);
        s[i] = s[i] + s[i - 1];
        hasp[s[i - 1]] ++;
        res += hasp[s[i] - k];

    }
    printf("%lld", res);
    
    return 0;
}


你可能感兴趣的:(AtCoder,A~E,c语言,c++,链表)