2017 Multi-University Training Contest

来源:互联网 发布:歌词有傻瓜的网络歌曲 编辑:程序博客网 时间:2024/04/25 00:08

比赛打到一半了,莫名有一种对未来的慌张,时间都过去一半了,还没有特别大的能力上的突破。这场比赛也是在拼罚时,最后一题和队友同时想到算法,很快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;}



原创粉丝点击