怪盗

链接:https://ac.nowcoder.com/acm/contest/5633/A

题目描述

一个长度为n+m+k包含n个数字1,m个数字2和k个数字4的数组,最多可能有多少个子序列1412?如果一个序列是数组的子序列,当且仅当这个序列可以由数组删去任意个元素,再将数组中的剩余元素按顺序排列而成

solusion

有一个数学规律,相同周长的矩形,正方形面积最大,因此我们可以将1分成两个最接近图片说明 整数相加,2和4都只取一个,因此2放在前半1后,4放在后半1后,所求答案就是图片说明 图片说明 图片说明 图片说明 图片说明 图片说明图片说明,并且a+b=n
如果n为偶数 a=b=n/2;
如果n为奇数 a=n/2+1;b=n/2;

#include <bits/stdc++.h>
using namespace std;
long long n,m,k,t;
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>m>>k;
        long long s=0;
        if(n%2==0)
            s=(n/2)*(n/2)*m*k;
        else
            s=(n/2+1)*(n/2)*m*k;
        cout<<s<<endl;
    }
}

B-Dis

链接:https://ac.nowcoder.com/acm/contest/5633/B

题目描述

给出一颗n{n}n个点n−1{n-1}n−1条边的树,点的编号为1,2,...,n−1,n{1,2,...,n-1,n}1,2,...,n−1,n,对于每个点i(1<=i<=n){i(1<=i<=n)}i(1<=i<=n),输出与点i{i}i距离为2{2}2的点的个数。 两个点的距离定义为两个点最短路径上的边的条数。

solusion

先将边用vector存储起来,在对每一个点进行遍历,如果e[i][j]!=i说明没对遍历的那个点进行重复相加,然后再对e[i]中的每个点计算其长度,相加并减去无向图反向的边

#include<bits/stdc++.h>
using namespace std;
int n,u,v,s;
vector<int> e[200005];
int main()
{
    cin>>n;
    for(int i=0;i<n-1;i++)
    {
        cin>>u>>v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    for(int i=1;i<=n;i++)
    {
        s=0;
        for(int j=0;j<e[i].size();j++)
        {
            if(e[i][j]!=i)
            s=s+e[e[i][j]].size()-1;
        }
        cout<<s<<endl;
    }
}

C-序列卷积之和

链接:https://ac.nowcoder.com/acm/contest/5633/C

题目描述

给出一个长度为n的数组a1,a2,...,an,计算图片说明并输出。

solusion

本题需要找规律
拿示例1
n=4;
a[]={6,7,8,9}
sum[]={6,13,21,30}
ss[]={6,19,40,70}
s1=a1 * (a1+a1+a2+a1+a2+a3+a1+a2+a3+a4)
s2=a2 * (a2+a2+a3+a2+a3+a4)
s3=a3 * (a3+a3+a4)
s4=a4 * a4
通过倒着求
pre=a4
s=a4 * pre+a3 *(pre+2a3) +a2 * (pre+2a3+3a2)+a1 *(pre+2a3+3a2+4a1)

#include<bits/stdc++.h>
using namespace std;
int n;
long long a[200005],sum[200005],ss[200005];
const int mod=1e9+7;
long long s=0,pre=0;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        sum[i]=(sum[i-1]+a[i])%mod;
        ss[i]=(ss[i-1]+sum[i])%mod;
    }
    for(int i=1;i<=n;i++)
    {
        pre=(a[i]*ss[n-i+1]%mod+pre)%mod;
    }
    for(int i=1;i<=n;i++)
    {
        s=(s+pre)%mod;
        pre=(pre-a[i]*ss[n-i+1]%mod+mod)%mod;
        cout<<pre<<endl;
    }
    cout<<s;
}