码迷,mamicode.com
首页 > 其他好文 > 详细

绵阳东辰国际test201909.28

时间:2019-09-28 16:17:44      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:运算   triangle   比较   c++   load   cst   problem   维护   def   

技术图片

老张原话:"这套题比较切合noip难度";我笑了

技术图片

数据为n<=1e5,ai<=1e18,k<=3!!!!!!

以下是考场时乱搞的代码,写的垃圾75分,没耐心的可以不用看跳过

#include<bits/stdc++.h>
#define ll long long
#define il inline
#define ri register int
using namespace std;
const int maxn=1e5+5;
int n,k,len;
ll a[maxn];
bool vis[maxn];
il bool cmp(ll a,ll b){return a>b;}
il int find(int l,int r,ll x){
    int mid,ans,prel=l;ans=l;
    if(r<l)return -1;
    while(l<=r){
        mid=l+r>>1;
        if(a[mid]>x)ans=mid,l=mid+1;
        else r=mid-1;
    } 
    if(a[ans]<=x)ans--;
    while(ans>=prel){
        if(vis[ans])ans--;
        else break;
    }
    if(ans>=prel)return ans;return -1;
}
il ll check(int l,int r){ll res=0;
   for(ri i=l;i<=r;i++)res+=a[i],vis[i]=false;
   int rr;
   for(ri i=l;i<=r-2;i++){
    if(vis[i])continue;rr=i+1;
    while(vis[rr])rr++;
    int t=find(rr+1,r,a[i]-a[rr]);
    if(t!=-1){vis[t]=true;vis[rr]=true;i++;}
    else return -1;
   }return res;
}
il int find2(int l,int r,ll x){
for(ri i=l;i<=r;i++)
if(a[i]>x)return i;
return -1;
}
il ll check2(int l,int r){ll res=0;
   for(ri i=l;i<=r;i++)res+=a[i],vis[i]=false;
   int rr;
   for(ri i=l;i<=r-2;i++){
    if(vis[i])continue;rr=i+1;
    while(vis[rr])rr++;
    int t=find2(rr+1,r,a[i]-a[rr]);
    if(t!=-1){vis[t]=true;vis[rr]=true;i++;}
    else return -1;
   }return res;
}
int main(){
    freopen("triangle.in","r",stdin);
    freopen("triangle.out","w",stdout);
    scanf("%d%d",&n,&k);len=k*3;
    for(ri i=1;i<=n;i++)scanf("%lld",&a[i]);
    sort(a+1,a+1+n,cmp);
    if(k==1){
        for(ri i=1;i+len-1<=n;i++){
        ll ans=check(i,i+len-1);
        if(ans!=-1){printf("%lld\n",ans);return 0;}
        else continue;
    }
    printf("-1\n");
    }
    else {
        ll ans;
        for(ri i=1;i+len-1<=n;i++){
         ans=check(i,i+len-1);
        if(ans==-1)continue;
        else break;
    }
    if(ans==-1)
        for(ri i=1;i+len-1<=n;i++){
        ans=check2(i,i+len-1);
        if(ans==-1)continue;
        else break;
    }
    if(ans!=-1)printf("%lld\n",ans);
    else printf("-1\n");}
    return 0;
}

考虑到k<=3,应从小数据进行突破

首先排序是肯定的(从大到小或从小到大都行)

这里就说从大到小

一:k==1

这种情况只有可能三条边排完序后是相连的三条(当然在保证能形成三角形的前提下)

怎么理解呢?假如a>b>c>d

如果a+b>c 显然a+b>d

但因为c>d 那么选d就没选 c 优秀

这样线性扫过去判断就可以

二:k==2

虽然最优解不一定是连续的6条边

但是如果将其中一个三 角形的攳条边删掉,那么第2个三角形在剩下的n?1条边中一定是连续的。

因此最优解要么是连续的6条边,要么是两组连续的3条边。对于连续的6条边我们枚举所 有组合的情况即可,

对于连续的3条边我们可以从大到小进行贪心。

三;k==3

k==1的k==2情况类似,只是更加复杂一些

最优解共4种情况:

情况1 连续9条边

情况2 连续6条长边和连续3条短边

情况3 连续3条长边和连续6条短边

情况4 3组连续的3条边

结合一下就行了

代码比较复杂,肯定都不想看于是就算了吧,

我知道你也不想读题,下面有题目大意

技术图片

第一题耗时过大,于是此题基本没啥时间了

题目大意
有一幅图,n个点,m条边,边有边权。

有三种操作:加边,删边,询问把图划分为两个点 集后两个端点属于同一个点集的边的最大值的最小值。

感觉特别眼熟?

https://www.luogu.org/problem/P1525

那道题没有修改操作,就简单多了,直接并查集维护即可

code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
struct NODE
{
    int x,y,val;//一个状态,需要保存3个量
};
struct cmp
{
    bool operator()(const NODE& a,const NODE& b)//重载运算符
    {
        return a.val<b.val;//重载
    }
};
priority_queue<NODE,vector<NODE>,cmp>gx;//大根堆(对于val)
int bcj[100000];//并查集
int find_(int node)//并查集找根节点过程
{
    if(bcj[node]!=node)return bcj[node]=find_(bcj[node]);
    return node;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int dr1,dr2,zhi;
    for(int i=1;i<=2*n;i++)bcj[i]=i;//初始化,记得是2*n
    while(m--)
    {
        scanf("%d%d%d",&dr1,&dr2,&zhi);
        gx.push((NODE){dr1,dr2,zhi});//加入队列
    }
    while(!gx.empty())//一直到没有冲突
    {
        if(find_(gx.top().x)==find_(gx.top().y))//如果在同一并查集内
        {
            printf("%d",gx.top().val);//直接输出
            return 0;
        }
        bcj[bcj[gx.top().x]]=bcj[find_(gx.top().y+n)];
        bcj[bcj[gx.top().y]]=bcj[find_(gx.top().x+n)];//维护新的关系,记得有两个并查集要维护
        gx.pop();
    }
    printf("%d",0);//特判0的情况
    return 0;
}

考虑有修改操作

part one如果还是向原来一样的话直接模拟50分是可以拿到的

绵阳东辰国际test201909.28

标签:运算   triangle   比较   c++   load   cst   problem   维护   def   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!