zoukankan      html  css  js  c++  java
  • 牛客多校第二场

      

    A:题意: 有一个n个点的圈标号为0-n-1    每次只能向相邻方向走一步  两个方向随机  每走到一个新的格子都会设立一个标记 (一开始在0设立标记) 问最后停在第m个格子的概率为多少   输出答案积

    概率为1/(n-1)    注意m为0的特殊情况即可

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=101;
    const ll mod=1e9+7;
    ll fast(ll x,ll n){ll ans=1;while(n){if(n&1)ans*=x,ans%=mod;x*=x;x%=mod;n>>=1 ; }return ans;  }
    ll n,m;
    int main()
    {
        ll ans=1;int cas;RI(cas);
        while(cas--)
        {
            scanf("%lld%lld",&n,&m);
            ll res;
            if(m==0)res=(n>1)?0:1;
            else res=fast(n-1,mod-2);
            ans*=res,ans%=mod;
            cout<<ans<<endl;
        }
    
    
    
        return 0;
    }
    View Code

    D:给出一个无向点权图  问点权第k大的团的点权为多少  

    bfs遍历即可  设置一个点权优先队列

    使用bitset来表示路径和 包含点 非常方便

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=101;
    struct node
    {
        ll sum;
        int id;
        bitset<N>s;
        bool operator < (const node & b)const
        {
            return sum>b.sum;
        }
    };
    
    int n,k,v[N];
    char ss[N];
    bitset<N>e[N];
    ll sol()
    {
        RII(n,k);
        rep(i,1,n)RI(v[i]);
    
        rep(i,1,n)
        {
            RS(ss+1);
            rep(j,1,n)
            {
                if(ss[j]=='1')e[i].set(j);
            }
        }
        bitset<N>s;
        s.reset();
        priority_queue<node>q;
        q.push(node{0,0,s});
    
        while(!q.empty())
        {
            node u=q.top();q.pop();
            if(--k==0)return u.sum;
            rep(i,u.id+1,n)
            {
                if(!u.s[i]&&(u.s&e[i])==u.s)
                {
                    u.s.set(i);
                    q.push(node{u.sum+1ll*v[i],i,u.s });
                    u.s.reset(i);
                }
            }
        }
    
        return -1;
    }
    int main()
    {
        printf("%lld",sol());
    }
    View Code

    E:

    给出一个nm 01矩阵 (迷宫)  1代表墙不能走  

    操作一  将x行y列 这个点反转  

    操作二  问第一行的x点到第n行的y点的路径个数

    用矩阵乘法来计算路径个数  用线段树来维护

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=1e4;
    const int mod=1e9+7;
    int n,m,q,b[50000+10][11];
    struct Matrix
    {
        ll a[11][11];
        friend Matrix operator*(const Matrix &a,const Matrix &b)
        {
            Matrix c;CLR(c.a,0);
            rep(i,1,m)rep(k,1,m)rep(j,1,m)
            c.a[i][j]=(c.a[i][j]+1ll*a.a[i][k]*b.a[k][j])%mod;
            return c;
        }
    }
    t[200000+10];
    
    void change(int *b,Matrix &ans)
    {
        CLR(ans.a,0);
        rep(i,1,m)
        {
            int j=i;
            for(;j>=1&&!b[j];ans.a[i][j]=1,--j);
            j=i;
            for(;j<=m&&!b[j];ans.a[i][j]=1,j++);
        }
    }
    void build(int l,int r,int pos)
    {
        if(l==r){change(b[l],t[pos]);return ;}
        int m=(l+r)>>1;build(lson);build(rson);
        t[pos]=t[pos<<1]*t[pos<<1|1];
    }
    
    void up(int x,int l,int r,int pos)
    {
        if(l==r){change(b[l],t[pos]);return ; }
        int m=(l+r)>>1;
        if(x<=m)up(x,lson);
        else if(x>m)up(x,rson);
        t[pos]=t[pos<<1]*t[pos<<1|1];
    }
    char s[100];
    int main()
    {
        scanf("%d%d%d",&n,&m,&q);
        rep(i,1,n){scanf("%s",s+1);rep(j,1,m)b[i][j]=s[j]-'0';}
        build(1,n,1);
        while(q--)
        {
            ll op,x,y;
            scanf("%lld%lld%lld",&op,&x,&y);
            if(op==1)b[x][y]^=1,up(x,1,n,1);
            else if(op==2)printf("%lld
    ",t[1].a[x][y]);
        }
    }
    View Code

    F:

    有2*n个人   和两个队伍 将这2*n个人分配到两个队伍使得每个队伍恰好n个人

    如果两个人分配到两个队伍会产生一个冲突mp[i][j](条件给出)  问能产生的最大冲突

    dfs

    如果dfs找到n个后再计算贡献呢的话复杂度为 C(2n,n) *n2

    可以边dfs边计算贡献  那么复杂度可以减一个n

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=1001;
    
    ll sum[N],mp[N][N],ans,ans1,vis[N];
    int n;
    
    void dfs(int cur,int num)
    {
        if(num==n+1)
        {
            ans=max(ans,ans1);return ;
        }
        rep(i,cur+1,2*n)
        {
            ll k=ans1;
            vis[num]=i;
            ans1+=sum[i];
            rep(j,1,num-1)
            ans1-=mp[i][vis[j]]*2;
            dfs(i,num+1);
            ans1=k;
        }
    }
    
    int main()
    {
        RI(n);
        rep(i,1,2*n)rep(j,1,2*n)scanf("%lld",&mp[i][j]),sum[i]+=mp[i][j];
        dfs(0,1);
        cout<<ans;
        return 0;
    }
    View Code

    H

    求第二大矩形

    比赛的时候扣四个点分别dp

    也可以用单调栈来维护

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    //////////////////////////////////
    const int N=1000+5;
    int dp[N][N];
    char mp[N][N];
    int ri[N][N],le[N][N],up[N][N];
    int main()
    {
        int s;
        int n,m;
        RII(n,m);
    
        rep(i,1,n)RS(mp[i]+1);
    
        rep(i,1,n)
        rep(j,1,m)
        {
            if(mp[i][j]=='1')mp[i][j]=1;
            else mp[i][j]=0;
            ri[i][j]=le[i][j]=j;
            up[i][j]=1;
        }
        rep(i,1,n)
        rep(j,2,m)
        if(mp[i][j]==mp[i][j-1]&&mp[i][j]==1)
        le[i][j]=le[i][j-1];
        rep(i,1,n)
        repp(j,m-1,1)
        if(mp[i][j]==mp[i][j+1]&&mp[i][j]==1)
        ri[i][j]=ri[i][j+1];
    
        int ans=0,maxx=0;
        int flagx=-1,flagy=-1;
    
    
    
    
        int chang,gao;
        rep(i,1,n)
        rep(j,1,m)
        if(mp[i][j])
        {
           if(i>1)
               if(mp[i-1][j])//如果状态需要转移的话
               {
                le[i][j]=max(le[i][j],le[i-1][j]);
                ri[i][j]=min(ri[i][j],ri[i-1][j]);
                up[i][j]=up[i-1][j]+1;
               }
            int d=ri[i][j]-le[i][j]+1;
            if(d*up[i][j]>maxx)
            {
                maxx=d*up[i][j];
                s=d*up[i][j];
    
                flagx=i;flagy=j;
                chang=d;gao=up[i][j];
                ans=max(s-d,s-(s/d));
            }
        }
        int x1,yy,x2,y2,x3,y3,x4,y4;
        //see(flagx);see(flagy);see(chang);see(gao);
    
        int shang=flagx-gao+1;
        int L=0,R=inf;
        //see(shang);
        rep(i,shang,flagx)
        {
            int l=flagy,r=flagy;
            while(mp[i][l-1]==1&&l-1>=1)l--;
            while(mp[i][r+1]==1&&r+1<=m)r++;
            L=max(L,l);
            R=min(R,r);
        }
    
        //see(L);see(R);
        x1=x2=shang;
        x3=x4=flagx;
        yy=L;y2=R;
        y3=L;y4=R;
        //see(x1);see(yy);see(x2);see(y2);see(x3);see(y3);see(x4);see(y4);
    
            maxx=0;
            mp[x1][yy]=0;
            rep(i,1,n)
            rep(j,1,m)
            {
                ri[i][j]=le[i][j]=j;
                up[i][j]=1;
            }
            rep(i,1,n)
            rep(j,2,m)
            if(mp[i][j]==mp[i][j-1]&&mp[i][j]==1)
            le[i][j]=le[i][j-1];
            rep(i,1,n)
            repp(j,m-1,1)
            if(mp[i][j]==mp[i][j+1]&&mp[i][j]==1)
            ri[i][j]=ri[i][j+1];
            rep(i,1,n)
            rep(j,1,m)
            if(mp[i][j])
            {
                    if(i>1)
                   if(mp[i-1][j])//如果状态需要转移的话
                   {
                        le[i][j]=max(le[i][j],le[i-1][j]);
                        ri[i][j]=min(ri[i][j],ri[i-1][j]);
                        up[i][j]=up[i-1][j]+1;
                   }
                int d=ri[i][j]-le[i][j]+1;
                s=d*up[i][j];
                maxx=max(maxx,s);
            }
            mp[x1][yy]=1;
    
            mp[x2][y2]=0;
            rep(i,1,n)
            rep(j,1,m)
            {
                ri[i][j]=le[i][j]=j;
                up[i][j]=1;
            }
            rep(i,1,n)
            rep(j,2,m)
            if(mp[i][j]==mp[i][j-1]&&mp[i][j]==1)
            le[i][j]=le[i][j-1];
            rep(i,1,n)
            repp(j,m-1,1)
            if(mp[i][j]==mp[i][j+1]&&mp[i][j]==1)
            ri[i][j]=ri[i][j+1];
            rep(i,1,n)
            rep(j,1,m)
            if(mp[i][j])
            {
                    if(i>1)
                   if(mp[i-1][j])//如果状态需要转移的话
                   {
                        le[i][j]=max(le[i][j],le[i-1][j]);
                        ri[i][j]=min(ri[i][j],ri[i-1][j]);
                        up[i][j]=up[i-1][j]+1;
                   }
                int d=ri[i][j]-le[i][j]+1;
                s=d*up[i][j];
                maxx=max(maxx,s);
            }
            mp[x2][y2]=1;
    
            mp[x3][y3]=0;
            rep(i,1,n)
            rep(j,1,m)
            {
                ri[i][j]=le[i][j]=j;
                up[i][j]=1;
            }
            rep(i,1,n)
            rep(j,2,m)
            if(mp[i][j]==mp[i][j-1]&&mp[i][j]==1)
            le[i][j]=le[i][j-1];
            rep(i,1,n)
            repp(j,m-1,1)
            if(mp[i][j]==mp[i][j+1]&&mp[i][j]==1)
            ri[i][j]=ri[i][j+1];
            rep(i,1,n)
            rep(j,1,m)
            if(mp[i][j])
            {
                    if(i>1)
                   if(mp[i-1][j])//如果状态需要转移的话
                   {
                        le[i][j]=max(le[i][j],le[i-1][j]);
                        ri[i][j]=min(ri[i][j],ri[i-1][j]);
                        up[i][j]=up[i-1][j]+1;
                   }
                int d=ri[i][j]-le[i][j]+1;
                s=d*up[i][j];
                maxx=max(maxx,s);
            }
            mp[x3][y3]=1;
    
            mp[x4][y4]=0;
            rep(i,1,n)
            rep(j,1,m)
            {
                ri[i][j]=le[i][j]=j;
                up[i][j]=1;
            }
            rep(i,1,n)
            rep(j,2,m)
            if(mp[i][j]==mp[i][j-1]&&mp[i][j]==1)
            le[i][j]=le[i][j-1];
            rep(i,1,n)
            repp(j,m-1,1)
            if(mp[i][j]==mp[i][j+1]&&mp[i][j]==1)
            ri[i][j]=ri[i][j+1];
            rep(i,1,n)
            rep(j,1,m)
            if(mp[i][j])
            {
                    if(i>1)
                   if(mp[i-1][j])//如果状态需要转移的话
                   {
                        le[i][j]=max(le[i][j],le[i-1][j]);
                        ri[i][j]=min(ri[i][j],ri[i-1][j]);
                        up[i][j]=up[i-1][j]+1;
                   }
                int d=ri[i][j]-le[i][j]+1;
                s=d*up[i][j];
                maxx=max(maxx,s);
            }
            mp[x4][y4]=1;
    
            printf("%d
    ",maxx);
    
    
        return 0;
    }
    View Code
  • 相关阅读:
    【转载】在Linux中使用VS Code编译调试C++项目
    【转载】Visual Studio 2015 for Linux更好地支持Linux下的开发
    【转载】ODBC, OLEDB, ADO, ADO.Net的演化简史
    【转载】OLE DB, ADO, ODBC关系与区别
    【转载】ADO,OLEDB,ODBC,DAO的区别
    【转载】Linux系统启动流程
    91. Decode Ways
    90. Subsets II
    89. Gray Code
    88. Merge Sorted Array
  • 原文地址:https://www.cnblogs.com/bxd123/p/11220535.html
Copyright © 2011-2022 走看看