• 【比赛】百度之星2017 初赛Round B


    第一题

    题意:给定n*m网络,定义两个棋子在同行同列则相互攻击,同时要求两个棋子的行和列不能一小一大,求满足条件的最大摆放的方案数。

    题解:ans=C(max(n,m),min(n,m)),就是在max中取min个数字的组合,组合内排序构成一种方案。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int read()
    {
        char c;int s=0,t=1;
        while(!isdigit(c=getchar()))if(c=='-')t=-1;
        do{s=s*10+c-'0';}while(isdigit(c=getchar()));
        return s*t;
    }
    /*------------------------------------------------------------*/
    const int inf=0x3f3f3f3f,MOD=1000000007;
    void gcd(ll a,ll b,ll& d,ll& x,ll& y)
    {
        if(!b){d=a;x=1;y=0;}
         else{gcd(b,a%b,d,y,x);y-=x*(a/b);}
    }
    ll inv(ll a,ll n)
    {
        ll d,x,y;
        gcd(a,n,d,x,y);
        return (x%n+n)%n;
    }
    ll n,fac[1010],fav[1010];
    
    int main()
    {
        ll T,n,m;
        scanf("%lld",&T);
        fac[0]=1;fav[0]=1;
        for(int i=1;i<=1001;i++)fac[i]=fac[i-1]*i%MOD;
        for(int i=1;i<=1001;i++)fav[i]=inv(fac[i],MOD);
        for(int i=1;i<=T;i++){
            scanf("%lld%lld",&n,&m);
            int mins=min(n,m);
            int maxs=max(n,m);
            printf("%lld
    ",fac[maxs]*fav[mins]%MOD*fav[maxs-mins]%MOD);
        }
        return 0;
    }
    View Code

    第二题

    第三题

    第四题

    第五题

    最小费用流(不要求最大流),不用拆点,S向每个点连边生产,每个点向T连边销售,点与点之间连无向边运输。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int read()
    {
        char c;int s=0,t=1;
        while(!isdigit(c=getchar()))if(c=='-')t=-1;
        do{s=s*10+c-'0';}while(isdigit(c=getchar()));
        return s*t;
    }
    /*------------------------------------------------------------*/
    const int inf=0x3f3f3f3f,maxn=600;
    struct edge{int from,v,flow,cost;}e[500000];
    int n,m,first[maxn],d[maxn],cur[maxn],ans,S,T,tot=1,q[10010];
    bool vis[maxn];
    void insert(int u,int v,int flow,int cost)
    {
        tot++;e[tot].v=v;e[tot].flow=flow;e[tot].cost=cost;e[tot].from=first[u];first[u]=tot;
        tot++;e[tot].v=u;e[tot].flow=0;e[tot].cost=-cost;e[tot].from=first[v];first[v]=tot;
    }
    bool spfa()
    {
        memset(vis,0,sizeof(vis));
        memset(d,0x3f,sizeof(d));
        int head=0,tail=1;q[0]=T;vis[T]=1;d[T]=0;
        while(head!=tail)
         {
             int x=q[head++];if(head>10000)head=0;
             for(int i=first[x];i;i=e[i].from)
              if(e[i^1].flow&&d[x]+e[i^1].cost<d[e[i].v])
               {
                   int y=e[i].v;
                   d[y]=d[x]+e[i^1].cost;
                   if(!vis[y])
                    {
                        if(d[y]<d[q[head]]){head--;if(head<0)head=10000;q[head]=y;}
                         else{q[tail++]=y;if(tail>10000)tail=0;}
                        vis[y]=1;
                    }
               }
             vis[x]=0;
         }
        return d[S]<0;
    }
    int dfs(int x,int a)
    {
        if(x==T||a==0)return a;
        vis[x]=1;
        int flow=0,f;
        for(int& i=cur[x];i;i=e[i].from)
         if(!vis[e[i].v]&&d[x]==e[i].cost+d[e[i].v]&&(f=dfs(e[i].v,min(a,e[i].flow)))>0)
          {
              e[i].flow-=f;
              e[i^1].flow+=f;
              ans+=e[i].cost*f;
              flow+=f;
              a-=f;
              if(a==0)break;
          }
        vis[x]=0;
        return flow;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)==2){
            S=0;T=n+1;
            int a1,b1,c1,d1,u1,v1,k1;
            tot=1;
            memset(first,0,sizeof(first));
            for(int i=1;i<=n;i++){
                a1=read();b1=read();c1=read();d1=read();
                insert(S,i,b1,a1);
                insert(i,T,d1,-c1);
            }
            for(int i=1;i<=m;i++){
                u1=read();v1=read();k1=read();
                if(u1==v1)continue;
                insert(u1,v1,inf,k1);
                insert(v1,u1,inf,k1);
            }
            ans=0;
            memset(vis,0,sizeof(vis));
            while(spfa())
             {
                 for(int i=S;i<=T;i++)cur[i]=first[i];
                 dfs(S,inf);
             }
            printf("%d
    ",-ans);
        }
        return 0;
    }
    View Code

    第六题

    题意:在无限的数轴上,给定n个区间,补充m个点使最长连续区间最长。n<=10^5。

    题解:

    区间左闭右开的好处:区间内距离和区间间距离直接计算,两区间左右端点重合就紧贴。

    经典区间交问题:左闭右开,按左端点排序,分类讨论三种情况:

    1.右端点<=R,包含。

    2.右端点>R,左端点<=R,相交。

    3.右端点>R,左端点>R,不相交。

    (另一种思路,左+1右-1,排序后前缀和为0时加入一个区间。)

    处理成若干个独立区间后,对于每个l计算出能延伸出最远的r,经典的双指针位移问题,多余的补充点直接加入答案。

    双指针位移:for左端点,每次扩展右端点到极限。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=200010;
    
    int n,m;
    struct cyc{int l,r;}a[maxn],b[maxn];
    
    bool cmp(cyc a,cyc b){return a.l<b.l;}
    
    int main(){
        while(scanf("%d%d",&n,&m)==2){
            for(int i=1;i<=n;i++){scanf("%d%d",&a[i].l,&a[i].r);a[i].r++;}
            sort(a+1,a+n+1,cmp);
            int L=a[1].l,R=a[1].r,tot=0;
            for(int i=2;i<=n;i++){
                if(a[i].r<=R)continue;
                if(a[i].r>R&&a[i].l<=R)R=a[i].r;
                else{b[++tot]=(cyc){L,R};L=a[i].l;R=a[i].r;}
            }
            b[++tot]=(cyc){L,R};
            n=tot;
            int j=1,leave=m,ans=0;
            for(int i=1;i<=n;i++){
                while(j+1<=n&&leave-(b[j+1].l-b[j].r)>=0){
                    leave-=b[j+1].l-b[j].r;
                    j++;
                }
                ans=max(ans,b[j].r-b[i].l+leave);
                leave+=b[i+1].l-b[i].r;
                if(i==j){j=i+1;leave=m;}
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    PS:进复赛啦>w<!

  • 相关阅读:
    CocoaPods常用的命令行以及安装方法
    成长轨迹51 【ACM算法之路 百炼poj.grids.cn】【字符串处理】【2744:子串】
    成长轨迹52 【ACM算法之路 百炼poj.grids.cn】【字符串处理】【2743:字符串判等】
    成长轨迹56 【ACM算法之路 百炼poj.grids.cn】【枚举】【2811:熄灯问题】
    嵌入式成长轨迹1 【嵌入式环境及基础】【嵌入式Linux软件开发入门】【linux基础命令】
    成长轨迹54 【ACM算法之路 百炼poj.grids.cn】【枚举】【2739:计算对数】
    嵌入式展望与学习路线
    嵌入式成长轨迹2【嵌入式环境及基础】【嵌入式Linux软件开发入门】【Shell脚本基础】
    成长轨迹53 【ACM算法之路 百炼poj.grids.cn】【枚举】【2747、2810、2692、2977】
    嵌入式学习轨迹
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7354521.html
Copyright © 2020-2023  润新知