省选模拟44

天天天天的挂大分!!!今天T1挂50,原因少判一个条件...

说实话今天的题怪没意思的,俩构造一交互,主要是数据范围迷到死

T1 构树

平方枚举直接连边

AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=1005;
int n,a[N],b[N],can;
bool ban;
pair<int,int> ans[N];
int fai[N];
int find(int x){return fai[x]==x?x:fai[x]=find(fai[x]);}
signed main(){
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    n=read();
    fo(i,1,n)fai[i]=i;
    fo(i,1,n){
        a[i]=read();b[i]=read();
        int fx=find(i),fy=find(a[i]);
        if(fx==fy&&a[a[i]]!=i&&b[a[i]]!=i)ban=true;
        else if(fx!=fy)fai[fx]=fy,ans[++can]=make_pair(a[i],i);
        if(a[i]==b[i])continue;
        fx=find(i);fy=find(b[i]);
        if(fx==fy&&a[b[i]]!=i&&b[b[i]]!=i)ban=true;
        else if(fx!=fy)fai[fx]=fy,ans[++can]=make_pair(b[i],i);
    }
    if(ban){printf("-1");return 0;}
    fo(i,1,n){
        fo(j,a[i]+1,b[i]-1){
            if(i<a[j]||i>b[j])continue;
            int fx=find(i),fy=find(j);
            if(fx==fy)continue;
            fai[fx]=fy;
            ans[++can]=make_pair(i,j);
        }
    }
    if(can==n-1){
        fo(i,1,n-1)printf("%d %d\n",ans[i].first,ans[i].second);
    }
    else printf("-1");
    return 0;
}

T2 交互

单调栈,考试的时候想到了,但是后来因为看错题了就不想这方面了,一开始看成了包含就返回true

由于这个树的特殊性,小于一个点的一定在这个点的左子树或者父亲

所以我们从小到大加入点,一旦子树满了,我们就弹出然后连边。。。

AC_code
#include<bits/stdc++.h>
#include"interact.h"
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=105;
int sta[N],top,l[N],r[N];
void guess(int n){
    if(n==1)return ;
    fo(i,1,n){
        int las=0;
        while(top&&query(sta[top],l[sta[top]],r[sta[top]])){
            if(las){
                report(sta[top],las);
            }
            las=sta[top];top--;
            if(top)r[sta[top]]=r[sta[top+1]];
        }
        l[i]=i;r[i]=i;
        if(las){
            report(i,las);
            l[i]=l[las];r[i]=i;
        }
        sta[++top]=i;
    }
    fo(i,1,top-1)report(sta[i],sta[i+1]);
}

T3 构图

平方暴力做,枚举有几个恰好k度的点,我考场上直接贪心了,假了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=1005;
int n,k,ans;
int g[N],h[N],f[N],sta[N],top;
int pre[N],ok[N],ned[N];
pair<int,int> res[N*N];
priority_queue<pair<int,int>> q;
signed main(){
    freopen("graph.in","r",stdin);
    freopen("graph.out","w",stdout);
    n=read();k=read();
    fo(i,k+2,n){
        int res;g[i]=0x3f3f3f3f;
        fo(j,1,i-k){
            if(j*k/(i-j)>=k+1)res=j*k;
            else res=j*k+((k+1-j*k/(i-j))*(i-j)-j*k%(i-j)-1)/2+1;
            // cerr<<i<<" "<<j<<" "<<res<<endl;
            if(res<g[i])g[i]=res,h[i]=j;
        }
    }
    memset(f,0x3f,sizeof(f));f[0]=0;
    fo(i,k+2,n)fo(j,0,i-k-2){
        if(f[i]>f[j]+g[i-j]){
            f[i]=f[j]+g[i-j];
            pre[i]=j;
        }
    }
    printf("%d\n",f[n]);
    int now=n;
    while(now){
        // cerr<<now<<" "<<pre[now]<<endl;
        int det=now-pre[now];
        // cerr<<h[det]<<endl;
        int sum=det-h[det],tmp=1,al=0;
        fo(i,1,h[det]){
            fo(j,1,k){
                res[++ans]=make_pair(i+pre[now],tmp+pre[now]+h[det]);
                tmp++;if(tmp>sum)tmp=1,al++;
            }
        }
        // cerr<<"SB"<<endl;
        ok[0]=tmp-1;
        fo(i,1,sum){
            ok[i]=ok[i-1]+1;
            if(ok[i]>sum)ok[i]=1;
        }
        int cha=1;
        fo(i,1,sum){
            if(ok[i]==1)al++;
            ned[ok[i]]=k+1-al;
            q.push(make_pair(ned[ok[i]],ok[i]));
        }
        while(!q.empty()){
            pair<int,int> x=q.top();q.pop();
            // cerr<<x.first<<endl;
            int sum=x.first;top=0;
            while(!q.empty()&&sum>0){
                res[++ans]=make_pair(x.second+pre[now]+h[det],q.top().second+pre[now]+h[det]);
                sta[++top]=q.top().second;ned[q.top().second]--;sum--;q.pop();
            }
            if(sum>0){
                fo(i,1,sum)res[++ans]=make_pair(x.second+pre[now]+h[det],i+pre[now]);
            }
            fo(i,1,top)if(ned[sta[i]])q.push(make_pair(ned[sta[i]],sta[i]));
        }
        now=pre[now];
    }
    fo(i,1,ans)printf("%d %d\n",res[i].first,res[i].second);
    return 0;
}
posted @ 2022-04-04 16:04  fengwu2005  阅读(61)  评论(0编辑  收藏  举报