绵阳东辰国际test2019.10.31

时间:2019-10-31
本文章向大家介绍绵阳东辰国际test2019.10.31,主要包括绵阳东辰国际test2019.10.31使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

吐槽:当时脑抽了,总是往难得地方想,实际上很简单一道签到题,总结以后要求自己第一题代码不能超过50行,不然就不要写(肯定就是方法错了)

分析:构造的时候就每次在它前面从大到小的放,这样保证肯定能消完的

code :

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
int a[300005],ans[300005];
int n1;
int c;
int main(){
    scanf("%d%d%d",&n,&m,&k);
    c=n-k;
    for(int i=1;i<=k;i++)scanf("%d",&a[i]);
    for(int i=1;i<=k;i++){
        for(int j=m;j>a[i]&&c;j--)ans[++n1]=j,c--;
        ans[++n1]=a[i];
    }
    if(n1!=n)printf("No");
    else{
        printf("Yes\n");
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    }
    return 0;
}

吐槽:n^3^log暴力炸了?,我真的是服了我自己了,代码功底太好了

这题数据用脚造的,暴力能过,这样这道题就毫无意义了

我们考虑一个显然的贪心:将所有没有连接的边放入一个堆中,并按照度数之和
从大到小进行排序。然后每次选出度数和最大的那个,把它们连起来,并将所有度数
和变化的点相邻的边重新加入堆中,重复上述过程

正解是n^3^的

但是事实上,注意到度数和不超过 2n,所以我们可以将堆换为 2n 个队列。

每次如果新加入的边度数和 ≥ K,那么我们就把他们直接连起来,否则加入对应和的队列中。
那么因为这样只有 < K 的队列会新增元素,所以我们每次考虑将 K 减少 1 之
后得到的队列并加入即可

code:

#include<bits/stdc++.h>
using namespace std;
#define CO const
#define IN inline
typedef long long LL;
template<class T> T read(){
    T x=0,w=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-') w=-w;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*w;
}
template<class T> IN T read(T&x){
    return x=read<T>();
}
int n;
int ans,rem,deg[501];
bool vis[501][501];
vector<pair<int,int> > vec[1001];
extern void extend(int u,int v);
void add(int u,int v){
    if(vis[u][v]) return;
    vis[u][v]=1,--rem;
    ++deg[u],++deg[v];
    for(int i=1;i<=n;++i){
        if(i!=u) extend(i,u);
        if(i!=v) extend(i,v);
    }
}
void extend(int u,int v){
    if(u>v) swap(u,v);
    if(deg[u]+deg[v]>=ans) add(u,v);
    else vec[deg[u]+deg[v]].push_back(make_pair(u,v));
}

int main(){
    read(n);
    int m=read<int>();
    for(int i=1;i<=m;++i){
        int u=read<int>(),v=read<int>();
        if(u>v) swap(u,v);
        vis[u][v]=1;
        ++deg[u],++deg[v];
    }
    ans=2*n,rem=n*(n-1)/2-m;
    for(int i=1;i<=n;++i)
        for(int j=i+1;j<=n;++j) extend(i,j);
    while(rem){
        while(ans and vec[ans].empty()) ans--;
        add(vec[ans].back().first,vec[ans].back().second);
        vec[ans].pop_back();
    }
    printf("%d\n",ans);
    return 0;
}

T3考试的时候没看,讲课的时候在睡觉,于是就跳过吧

原文地址:https://www.cnblogs.com/wzxbeliever/p/11772064.html