松鼠分松果解题 c++

松鼠分松果解题 c++

题目

描述

在一个天气晴朗的早晨,有k只可爱的小松鼠来到文山湖旁,看见地上有n堆松果

松鼠王国有一个规定,看到有很多堆松果时,取松果的堆数必须连续。比如只能取第2堆,第3堆,第4堆的松果,而不能取第2堆,第3堆,第5堆的松果。当然,只取其中一堆松果也是没有问题的。

而且,为了王国的公平正义,取完松果后,松果的总数必须能让k只小松鼠平分

所以,请聪明的你帮笨笨的小松鼠算一算,到底有多少种取法呢?

输入
第一行输入松果的堆数n,其中1 <= n <= 3 * 10^41<=n<=3∗10
4

第二行输入从第1堆到第n堆,每堆的松果个数,每个数字用空格分隔,其中 0 < 每堆的松果数 < 10^40<每堆的松果数<10
4

第三行输入松鼠的个数k,其中2 <= k <= 10^42<=k<=10
4

输出
输出一个整数,表示有多少种取法

理解

就是说如果要去连续堆的数字,而且数字应该是要可以被k整除的
所以在此,另有其人提供了思路(wu,确实很难想
就是 如果这一堆可以被k整除,那么前一个数/k的余数是和这一堆后一个数/k的余数是一样的,那么我们只要计算出到底有多少个余数一样
计算出来之后,得到的a,可以得知如果每一堆的松果可以相互连接形成一个更大的堆,所以,我们需要像计算比赛场数一样,得到的取法为 a + (a-1)+(a-2)…
通过等差求和公式又可以进行简化
最后得到以下的代码

c++

#include 
using namespace std;

int main()
{   
    int n_time,get,b[30002],qianzui[30002],num;
    
    cin>>n_time;
    for (int i = 0; i < n_time; i++)
    {   
        cin>>b[i];
    }
    cin>>num;
    qianzui[0]=0;
    for (int i = 1; i <= n_time; i++)
    {
        qianzui[i]=b[i-1]+qianzui[i-1];
    }
    int chunchu[30002]={0};
    for (int i = 0; i <= n_time; i++)
    {   
        chunchu[qianzui[i]%num]++;
    }    
    int result=0;
    for (int i = 0; i <= n_time; i++)
    {   
        int m =chunchu[i]-1;

        result += (m+1)*m/2 ;
   
    }
    cout<<result;
}

python

a = input()
b = [int(i) for i in input().split()]
math = int(input())
res = 0
qianzui = [b[0]]
all_res = 0
for i in range(1,len(b)):
    qianzui.append(qianzui[i-1]+b[i])
qianzui.insert(0,0)
yushu = [int(i%math) for i in qianzui]
def answer(x):
    w= 0
    for i in range(1,x+1):
        w += i
    return w
for chu in range(0,math):
    test = yushu.count(chu)-1
    all_res += answer(test)
print(all_res)

你可能感兴趣的:(c++,算法,开发语言)