ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

省选模拟28

2022-03-08 19:00:30  阅读:143  来源: 互联网

标签:ch const 省选 28 ++ int VEC return 模拟


这两天不知道咋了,精神抖擞,考试没有睡觉......

第一题,有点意思,一步一步往外推,先推到拓扑序,意识到需要缩点,然后发现要用网络流,可以说是搞了好久

第二题,一眼看上去没有思路,果断放弃

第三题,仍然没有思路

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*10+ch-'0';ch=getchar();}
    return s*t;
}
const int N=65;
const int inf=0x3f3f3f3f;
int T,n,m,ys[N*2],cys,buc[N],ans;
char ch[N],s[4005][5];
struct E{int to,nxt;}e[4005];
int head[N],rp;
void add_edg(int x,int y){
    e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;
}
int dfn[N],low[N],cnt,cd[N];
bool vi[N];
int bl[N],hav[N],siz[N],cbl,sta[N],top;
void tarjan(int x){
    dfn[x]=low[x]=++cnt;sta[++top]=x;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);
        else if(!bl[y])low[x]=min(low[x],dfn[y]);
    }
    if(dfn[x]==low[x]){
        bl[x]=++cbl;siz[cbl]++;
        if(!buc[x])hav[cbl]++;
        while(sta[top]!=x){
            bl[sta[top]]=cbl;
            if(!buc[sta[top]])hav[cbl]++;
            top--;siz[cbl]++;
        }top--;
    }
}
struct NET{
    int s=126,t=127;
    struct E{int to,nxt,val;}e[4205*10];
    int head[N*2],hea[N*2],rp;
    void add_edg(int x,int y,int z){
        e[++rp].to=y;e[rp].nxt=head[x];
        e[rp].val=z;head[x]=rp;
    }
    void clear(){memset(head,0,sizeof(head));rp=1;}
    int dis[N*2];
    bool bfs(){
        memcpy(head,hea,sizeof(hea));
        memset(dis,0x3f,sizeof(dis));
        queue<int> q;while(!q.empty())q.pop();
        q.push(s);dis[s]=0;
        while(!q.empty()){
            int x=q.front();q.pop();
            // cerr<<x<<endl;
            for(int i=head[x];i;i=e[i].nxt){
                int y=e[i].to;
                // cerr<<x<<" "<<y<<" "<<e[i].val<<" "<<dis[y]<<endl;
                if(!e[i].val||dis[y]<=dis[x]+1)continue;
                dis[y]=dis[x]+1;q.push(y);
                if(y==t)return true;
            }
        }
        return false;
    }
    int dfs(int x,int in){
        if(x==t)return in;
        int go=0,rest=in;
        // cerr<<x<<" "<<in<<endl;
        for(int i=head[x];i;head[x]=i=e[i].nxt){
            int y=e[i].to;
            if(!e[i].val||dis[y]!=dis[x]+1)continue;
            go=dfs(y,min(e[i].val,rest));
            if(go)rest-=go,e[i].val-=go,e[i^1].val+=go;
            else dis[y]=0;
            if(!rest)break;
        }
        return in-rest;
    }
    int dinic(){
        int ret=0;
        memcpy(hea,head,sizeof(hea));
        while(bfs())ret+=dfs(s,inf);
        return ret;
    }
}net;
signed main(){
    freopen("graph.in","r",stdin);
    freopen("graph.out","w",stdout);
    // cerr<<(int)'Z'<<" "<<(int)'z'<<" "<<(int)'9'<<endl;
    T=read();
    fo(i,'0','9')ys[i]=++cys;
    fo(i,'a','z')ys[i]=++cys;
    fo(i,'A','Z')ys[i]=++cys;
    while(T--){
        // cerr<<ys['a']<<endl;
        memset(buc,0,sizeof(buc));
        memset(bl,0,sizeof(bl));
        memset(hav,0,sizeof(hav));
        memset(siz,0,sizeof(siz));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(cd,0,sizeof(cd));
        memset(vi,false,sizeof(vi));
        memset(head,0,sizeof(head));
        rp=cbl=cnt=ans=top=0;net.clear();
        scanf("%s",ch+1);m=read();
        n=strlen(ch+1);
        fo(i,1,n)buc[ys[ch[i]]]++;
        fo(i,1,m){
            scanf("%s",s[i]+1);
            add_edg(ys[s[i][1]],ys[s[i][2]]);
        }
        fo(i,1,cys){if(!bl[i])tarjan(i);if(buc[i])ans++;}
        // cerr<<ans<<endl;
        fo(i,1,m)cd[bl[ys[s[i][1]]]]++;
        fo(i,1,cbl){
            if(!hav[i]&&(cd[i]||siz[i]>1)){
                ans--;hav[i]++;vi[i]=true;
                net.add_edg(net.s,i,1);
                net.add_edg(i,net.s,0);
            }
            net.add_edg(i+cbl,net.t,hav[i]);
            net.add_edg(net.t,i+cbl,0);
        }
        // cerr<<ans<<endl;
        fo(i,1,m){
            if(bl[ys[s[i][1]]]!=bl[ys[s[i][2]]]){
                net.add_edg(bl[ys[s[i][1]]],bl[ys[s[i][2]]]+cbl,inf);
                net.add_edg(bl[ys[s[i][2]]]+cbl,bl[ys[s[i][1]]],0);
                // net.add_edg(bl[ys[s[i][1]]]+cbl,bl[ys[s[i][2]]],inf);
                // net.add_edg(bl[ys[s[i][2]]],bl[ys[s[i][1]]]+cbl,0);
                net.add_edg(bl[ys[s[i][1]]]+cbl,bl[ys[s[i][2]]]+cbl,inf);
                net.add_edg(bl[ys[s[i][2]]]+cbl,bl[ys[s[i][1]]]+cbl,0);
            }
        }
        printf("%d\n",ans+net.dinic());
    }
    return 0;
}

T2 想不出

欧拉定理,然后找最大的交点数就行了,直接根据左右两侧的点个数定向!!

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*10+ch-'0';ch=getchar();}
    return s*t;
}
const int N=2005;
const double eps=1e-15;
struct VEC{
    double x,y;
    VEC(){}VEC(double a,double b){x=a;y=b;}
    VEC operator + (VEC a)const{return VEC(x+a.x,y+a.y);}
    VEC operator - (VEC a)const{return VEC(x-a.x,y-a.y);}
    VEC operator * (double a)const{return VEC(x*a,y*a);}
    VEC operator / (double a)const{return VEC(x/a,y/a);}
    double operator * (VEC a)const{return x*a.x+y*a.y;}
    double operator ^ (VEC a)const{return x*a.y-y*a.x;}
}dot[N],ll[N],rr[N],zx,yx;
int n,ans,cl,cr;
bool judle(VEC x,VEC y){
    VEC dw=VEC(-1.0,-sqrt(3.0)),up=VEC(-1.0,sqrt(3.0));
    return ((dw^(x-y))<=0&&(up^(x-y))>=0);
}
bool judri(VEC x,VEC y){
    VEC dw=VEC(1.0,-sqrt(3.0)),up=VEC(1.0,sqrt(3.0));
    return ((dw^(x-y))>=0&&(up^(x-y))<=0);
}
bool coml(VEC a,VEC b){
    return a.x==b.x?a.y<b.y:a.x<b.x;
}
signed main(){
    freopen("surface.in","r",stdin);
    freopen("surface.out","w",stdout);
    n=read();int u=(1<<n)-1;
    fo(i,1,n)scanf("%lf%lf",&dot[i].x,&dot[i].y);
    zx=VEC(-1.0,-sqrt(3.0));
    yx=VEC(1.0,-sqrt(3.0));
    fo(i,1,n){
        int le=0,ri=0;
        fo(j,1,n){
            if(i==j)continue;
            if(judle(dot[j],dot[i]))le++;
            if(judri(dot[j],dot[i]))ri++;
        }
        if(le>=ri)ll[++cl]=dot[i];
        else rr[++cr]=dot[i];
    }
    sort(ll+1,ll+cl+1,coml);
    fo(i,1,cl){
        fo(j,1,cr){
            if((zx^(rr[j]-ll[i]))>0)continue;
            if((yx^(ll[i]-rr[j]))<0)continue;
            ans++;
        }
    }
    ans=ans+1-n;
    printf("%d",ans);
    return 0;
}

T3 题目名称

不会

标签:ch,const,省选,28,++,int,VEC,return,模拟
来源: https://www.cnblogs.com/hzoi-fengwu/p/15982012.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有