2017 Multi-University Training Contest - Team 5

比赛打到一半了,莫名有一种对未来的慌张,时间都过去一半了,还没有特别大的能力上的突破。这场比赛也是在拼罚时,最后一题和队友同时想到算法,很快ac。T6和T8出的太慢了,导致我们罚时输了很多很多。能切几题确实很重要,但是目前更大的问题反而是我们队的罚时,这点很致命。


1006 Rikka with Graph

考虑贪心地一条一条边添加进去。

当 m \leq n-1mn1 时,我们需要最小化距离为 nn 的点对数,所以肯定是连出一个大小为 m+1m+1 的联通块,剩下的点都是孤立点。在这个联通块中,为了最小化内部的距离和,肯定是连成一个菊花的形状,即一个点和剩下所有点直接相邻。

当 m > n-1m>n1 时,肯定先用最开始 n-1n1 条边连成一个菊花,这时任意两点之间距离的最大值是 22。因此剩下的每一条边唯一的作用就是将一对点的距离缩减为 11

这样我们就能知道了最终图的形状了,稍加计算就能得到答案。要注意 mm 有可能大于 \frac{n(n-1)}{2}2n(n1)

#include "stdio.h"
#include "iostream"
#include "cstring"

using namespace std;
typedef long long ll;
int main(int argc, char const *argv[])
{
    int t;
    while(cin>>t)
    {
        while(t--)
        {
            ll n,m;
            cin>>n>>m;
            ll ans=0;
            if(m*2>=(n*n-n))
            {
                ans=n*n-n;
            }
            else if(m>=n-1)
            {
                ans=2*n*(n-1)-2*m;

            }else{
                ans=n*n*n-n*n-(m*m+m)*n+2*m*m;
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}

1008 Rikka with Subset

签到题,大致的思想就是反过来的背包。

如果 B_iBi 是 BB 数组中除了 B_0B0 以外第一个值不为 00 的位置,那么显然 ii 就是 AA 中的最小数。

现在需要求出删掉 ii 后的 BB 数组,过程大概是反向的背包,即从小到大让 B_j-=B_{j-i}Bj=Bji

时间复杂度 O(nm)O(nm)


#include<bits/stdc++.h>

using namespace std;

int n,m;
int a[10005],ans[10005],S[10005],tmp[10005];

int main()
{
    int T;
    cin>>T;
    while (T--)
    {
        scanf("%d%d",&n,&m);
        for (int i=0;i<=m;i++) scanf("%d",a+i);
        
        memset(S,0,sizeof(S));
        S[0]=1;
        int top=0;
        for (int i=0;i<=m;i++)
        {
            while (S[i]<a[i])
            {
                memcpy(tmp,S,sizeof(S));
                for (int j=0;j<=m;j++)
                {
                    if (tmp[j]==0) continue;
                    S[i+j]+=tmp[j];
                }
                top++;
                ans[top]=i;
            }
            if (top>=n) break;
        }
        for (int i=1;i<n;i++) printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}

1011 Rikka with Competition

临时加的签到题。把  a_iai  从大到小排序,那么第  ii  强人要获胜,最优情况下是最强的人输给了第二强的人,第二强的人输给了第三强的人,以此类推。因此只需要判断排序后  \max_{j<i} (a_j-a_{j+1})maxj<i(ajaj+1)  和  KK 的大小关系即可。

时间复杂度 O(n \log n)O(nlogn)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <string>

using namespace std;
typedef long long ll;
const int MAXN=100100;

int arr[MAXN];

int main(int argc, char const *argv[])
{
    //freopen("input.txt","r",stdin);
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        cin>>n>>k;
        for(int i=0;i<n;++i)
            scanf("%d",&arr[i]);
        sort(arr,arr+n);
        int ans=1;
        for (int i = n-1; i > 0; --i)
        {
            if(arr[i]-arr[i-1]<=k)
                ans++;
            else break;
        }
        cout<<ans<<endl;
    }   
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值