zoukankan      html  css  js  c++  java
  • 3/5福建四校联考

    1.有3只小猪,三只大猪。大猪和其中一只小猪会划船。船最多可以坐两个人,四只小猪划船的时间是tA,tB,tC,ta,如果载人的话时间翻倍,求最小时间。

    题解:暴力搜索。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define INF 2000000000
    #define a A+3
    #define b B+3
    #define c C+3
    #define to 127
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    } 
    
    int t[10],ans=INF;
    int s[10];
    int has[10];
    int d[127];
    
    bool check()
    {
        for(int i=4;i<=6;i++)
           if(has[i]!=has[i-3])
               for(int j=1;j<=3;j++)
                  if(j!=i-3&&has[j]==has[i])
                          return true;
        return false;
    }
    
    bool check(int x,int y,int k)
    {
        if(has[x]==k||has[y]==k)return false;
        if(x==y)return false;
        if(!(x>=4)^(y>=4))return true;
        if(x!=y-3&&y!=x-3)return false;
        return true;
    }
    
    void dfs(int k,int T,int x)
    {
        if(check())return;
        if(T>=d[x^((k==0)?64:0)])return;else d[x^((k==0)?64:0)]=T;
        if((x^((k==0)?64:0))==to){ans=min(ans,T);}
        for(int i=1;i<=4;i++)if(has[i]!=k)
        {has[i]^=1;dfs(!k,T+t[i],x^s[i]);has[i]^=1;}
        for(int i=1;i<=4;i++)
            for(int j=1;j<=6;j++)
                if(check(i,j,k)) {has[i]^=1;has[j]^=1;dfs(!k,T+2*t[i],x^s[i]^s[j]);has[i]^=1;has[j]^=1;}
    }
    
    int main()
    {
        freopen("boat.in","r",stdin);
        freopen("boat.out","w",stdout);
        for(int i=0;i<128;i++)d[i]=INF;
        for(int i=1;i<=4;i++)t[i]=read();s[1]=1;
        for(int i=2;i<=7;i++)s[i]=s[i-1]<<1;
        dfs(1,0,0);
        cout<<ans;
        return 0;
    }

    2.有一个n(n<=100)个点m条边的图,可能有负权边,你可以把所有边都加上或减去一个值,求第1个点到第n个点的距离非负的最小值。

    题解:不考虑那些到不了n点的点(可以用floyd判一下),然后二分一个答案,判断有没有负环就可以了。复杂度o(能过)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define ll long long
    #define MAXN 100000
    #define MAXL 100
    #define INF 1000000000
    #define inf 2000000000000LL
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    queue<int> q;
    int n,m,cnt=0;
    struct edge{
        int to,next;
        ll w;
    }e[MAXN+5];
    bool inq[MAXL+5];
    ll mp[MAXL+5][MAXL+5];
    ll d[MAXL+5];
    int head[MAXL+5];
    ll ans=INF;
    bool yes;
    
    inline void ins(int f,int t,int w)
    {
        e[++cnt].next=head[f];head[f]=cnt;
        e[cnt].to=t;e[cnt].w=w;
    }
    
    void dfs(int x,int ad)
    {
        if(!yes)return;inq[x]=1;
        for(int i=head[x];i;i=e[i].next)
            if(mp[e[i].to][n]<INF&&d[x]+ad+e[i].w<d[e[i].to])
            {
                d[e[i].to]=d[x]+ad+e[i].w;if(inq[e[i].to]){yes=false;return;}
                dfs(e[i].to,ad);
            }
        inq[x]=0;
    }
    
    int main()
    {
        freopen("planet.in","r",stdin);
        freopen("planet.out","w",stdout);
        int T=read();
        while(T--)
        {
            n=read();m=read();cnt=0;ans=inf;memset(head,0,sizeof(head));
            for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)mp[i][j]=INF;
            for(int i=1;i<=n;i++)mp[i][i]=0;
            for(int i=1;i<=m;i++)
            {int u=read(),v=read(),w=read();ins(u,v,w);mp[u][v]=min(mp[u][v],(ll)w);}
            for(int k=1;k<=n;k++)
                for(int i=1;i<=n;i++)
                    for(int j=1;j<=n;j++)
                        if(mp[i][k]<INF&&mp[k][j]<INF&&mp[i][k]+mp[k][j]<mp[i][j]) mp[i][j]=mp[i][k]+mp[k][j];
            int l=-INF,r=INF,mid;
            while(l<=r)
            {
                mid=(l+r)>>1;yes=true;memset(inq,0,sizeof(inq));
                for(int i=1;i<=n;i++)d[i]=inf;d[1]=0;dfs(1,mid);
                if(yes&&d[n]>=0&&d[n]!=inf)r=mid-1,ans=d[n];
                else l=mid+1;
            }
            if(ans==inf)puts("-1");
            else printf("%lld
    ",ans);
        }
        return 0;
    }

    3.有n个点,每个点有pi堆东西,最多卖掉si堆东西。对于每队1<=i<j<=n,i可以向j运送最多c堆东西,求最多能销售多少堆东西。n<=10000

    题解:对于60%,n<=100,就成为了一个裸的网络流模型。每个点向S连pi,向t连si,然后每队点连c的边就可以了。

    对于100%,我们发现我们每次做的事情就是求最小割,而这个图的中间的边都是c的,所以我们可以直接考虑每个点割到S还是到T

    用f[i][j]表示前i个点,有j个点割到S的最小割。f[i][j]=min(f[i-1][j-1]+p[i]+(i-j)*c,f[i-1][j]+s[i])  复杂度n^2

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define ll long long
    #define INF 2000000000000000LL
    using namespace std;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    ll f[2][10005];
    ll s[10005];
    ll p[10005];
    int n;ll c;
    
    int main()
    {
        freopen("deliver.in","r",stdin);
        freopen("deliver.out","w",stdout);
        n=read();c=read();
        for(int i=1;i<=n;i++)p[i]=read();
        for(int i=1;i<=n;i++)s[i]=read();
        int nown=1,pre=0;
        for(int j=1;j<=n;j++)f[0][j]=f[1][j]=INF;    
        for(int i=1;i<=n;i++)
        {
            f[nown][0]=f[pre][0]+s[i];
            for(int j=1;j<=i;j++)
                f[nown][j]=min(f[pre][j-1]+p[i]+(i-j)*c,f[pre][j]+s[i]);
            nown=1-nown;pre=1-pre;
        }
        ll ans=INF;
        for(int i=0;i<=n;i++)
            ans=min(ans,f[pre][i]);
        cout<<ans;
        return 0;
    }

    4.有一个数字游戏,一开始有两个数1 1,然后每次可以选择其中一个数变成两个数的和。给定最后的状态n,m(<=10^18),求最少已经玩了多少次。

    题解:求gcd,gcd是1的时候有解,答案是辗转相除的步数。

    这道题居然还有负数,被坑了。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define ll long long
    using namespace std;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    } 
    
    ll ans=-1;
    
    ll gcd(ll x,ll y)
    {
        if(x<y) {ll t=x;x=y;y=t;}
        if(y==0)return x;ans+=x/y;
        return gcd(y,x%y);
    }
    
    int main()
    {
        freopen("math.in","r",stdin);
        freopen("math.out","w",stdout);
        ll x=read(),y=read();
        if(x<=0||y<=0) return 0*puts("-1");
        if(gcd(x,y)!=1)puts("-1");
        else printf("%I64d
    ",ans);
        return 0;
    }
  • 相关阅读:
    gvim在windows下的一些小技巧
    解决eclipse在ubuntu下无法找到jdk方法
    ubuntu 12.04 下安装wireshark
    使用坚果云同步数据
    Windows WMIC命令详解 (Windows Management Instrumentation Commandline)
    ubuntu 12.04 配置指南
    CHROME自定义样式扩展 —— STYLISH
    地漏
    卫生间装修,想要坐便改成蹲便,地面需要加高多少?
    不锈钢橱柜
  • 原文地址:https://www.cnblogs.com/FallDream/p/liankao35.html
Copyright © 2011-2022 走看看