• 寒假2


    给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。


    你能求出数列中总共有多少个K倍区间吗?
    输入
    第一行包含两个整数N和K。(1 <= N, K <= 100000)
    以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
    输出
    输出一个整数,代表K倍区间的数目。
    样例输入
    5 2
    1
    2
    3
    4
    5
    样例输出
    6

    求区间[l,r]的和是k的倍数的个数。求区间和,我们可以通过前缀和来求出。我们规定sum[i]表示第1个元素到第i个元素的和。那么sum[r] - sum[l-1]就是区间[l,r]的和。区间[l,r]的和是k的倍数即(sum[r] - sum[l-1])%k == 0 即sum[r]%k == sum[l-1]%k
      那么,我们求出每个前缀和,在求的过程中取模,两个相等的前缀和就能组成一个k倍区间。我们可以在计算完前缀和以后,使用两层for循环来计数k倍区间的个数。但是由于数据量较大,这样是会超时的。

    #include<iostream>
    #include<bits/stdc++.h>
    using namespace std;
    int a[100005],str[100005],cnt[100005];
    int main()
    {
       int n,k,i,j;
       cin>>n>>k;
       for(i=0;i<n;i++)
       {
          cin>>a[i];
          str[i]=(str[i-1]+a[i])%k;
       }
        long long ans=0;
      for(i=0;i<n;i++)
      {
          ans+=cnt[str[i]];
        cnt[str[i]]++;
    
      }
      cout<<ans+cnt[0]<<endl;
      return 0;
    }
    小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子。每种蒸笼都有非常多笼,可以认为是无限笼。


    每当有顾客想买X个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有X个包子。比如一共有3种蒸笼,分别能放3、4和5个包子。当顾客想买11个包子时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的)。


    当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有3种蒸笼,分别能放4、5和6个包子。而顾客想买7个包子时,大叔就凑不出来了。


    小明想知道一共有多少种数目是包子大叔凑不出来的。
    输入
    第一行包含一个整数N。(1 <= N <= 100)
    以下N行每行包含一个整数Ai。(1 <= Ai <= 100)
    输出
    一个整数代表答案。如果凑不出的数目有无限多个,输出INF。
    样例输入
    2
    4
    5
    样例输出
    6

    拓展欧几里德:

    1. 求整数 x和y 使得 ax + by = 1.

    2. 可以发现, 如果gcd(a, b) ≠ 1,则显然无解.

    3. 反之, 如果gcd(a, b) = 1, 则可以通过拓展原来的 辗转相除法 来求解.

    4. 事实上,一定存在整数对(x, y)使得ax+by = gcd(a,b) = 1

    如果所有 蒸笼里的包子数的最大公约数,不为1,则说明有无数种数目凑不出来。如果最大公约数为1,则说明有限个数目凑不出来。

    #include<iostream>
    #include<bits/stdc++.h>
    using namespace std;
    int a[101],dp[10002];
    int gcd(int a,int b)
    {
        return b==0?a:gcd(b,a%b);
    }
    int main()
    {
        int n;
        cin>>n;
        int i,j;
        for(i=0;i<n;i++)
        {
            cin>>a[i];
        }
        int t=a[0];
        for(i=1;i<n;i++)
        {
            t=gcd(t,a[i]);
        }
        if(t!=1)
            cout<<"INF"<<endl;
        else
        {
            dp[0]=1;
            for(i=0;i<n;i++)
            {
                for(j=0;j+a[i]<10002;j++)
                {
                    if(dp[j])
                    {
                        dp[j+a[i]]=1;
                    }
                }
            }
            long long ans=0;
            for(i=0;i<10002;i++)
            {
                if(!dp[i])
                    ans++;
            }
            cout<<ans<<endl;
        }
        return 0;
    }



    方格分割

    1. 6x6的方格,沿着格子的边线剪开成两部分。
    2. 要求这两部分的形状完全相同。
    3. 试计算:
    4. 包括这3种分法在内,一共有多少种不同的分割方法。

    可以转换为,这是一个 6 x 6的矩阵,将[3, 3]位置看成起点,分相反的两条路径开始搜索(标志),当搜索到 边界时就是停止遍历 (r == 0 || c == 0 || r == 6 || c == 6) ,即是一种方案。这显然是经典的回溯问题,但是要注意这要对两条相反的路径进行标志。最后方案数/4, 因为旋转对称属于一种方案(4个方向嘛)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    const int maxn = 6 + 2;
    bool used[maxn][maxn];
    int ans;
    int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    void dfs(int r, int c)
    {
        if (r == 0 || c == 0 || r == 6 || c == 6) {
            ans++;
            return;
        }
        for (int i = 0; i < 4; i++)
        {
            int rx = r + dir[i][0], ry = c + dir[i][1];
            if (!used[rx][ry])
            {
                used[rx][ry] = true;
                used[6 - rx][6 - ry] = true;
                dfs(rx, ry);
                used[rx][ry] = false;
                used[6 - rx][6 - ry] = false;
            }
        }
    }
    void solve()
    {
        memset(used, 0, sizeof(used));
        used[3][3] = true;
        dfs(3, 3);
        cout << ans / 4 << endl;
    }
    int main()
    {
        solve();
        return 0; 
    }
  • 相关阅读:
    Linux文本检索命令grep笔记
    Linux文本检索命令grep笔记
    Linux文件查询笔记
    Linux文件查询笔记
    Linux文件默认权限和umask笔记
    Linux文件默认权限和umask笔记
    Linux关于文件的权限笔记
    Linux关于文件的权限笔记
    Linux文件操作实用笔记
    6.创建自定义菜单
  • 原文地址:https://www.cnblogs.com/kepa/p/10446936.html
Copyright © 2020-2023  润新知