zoukankan      html  css  js  c++  java
  • 2015浙江财经大学ACM有奖周赛(一) 题解报告

    2015浙江财经大学ACM有奖周赛(一) 题解报告

    命题:丽丽&&黑鸡

    这是命题者原话。

    题目涉及的知识面比较广泛,有深度优先搜索、广度优先搜索、数学题、几何题、贪心算法、枚举、二进制等等...

    有些题目还需要大家对程序的效率做出优化..大一的小宝宝可能有一些吃不消..当成是一种体验就好了。

    题解目录:

    ZUFE OJ 2307: 最长连续不下降子串
    ZUFE OJ 2308: Lucky Number
    ZUFE OJ 2309: 小明爱吃面
    ZUFE OJ 2310: 小明爱消除
    ZUFE OJ 2311: 找数字
    ZUFE OJ 2312: 简单数学题
    ZUFE OJ 2313: 字符串还原
    ZUFE OJ 2314: 矩形周长
    ZUFE OJ 2315: 小明的智力
    ZUFE OJ 2316: 水题
    ZUFE OJ 2317: 画个圈圈
    ZUFE OJ 2318: 跳格子
    ZUFE OJ 2320: 高中几何没学好
    ZUFE OJ 1606: 清洁公司
    ZUFE OJ 2323: 黑鸡跑1000

    /*
    ZUFE OJ 2307: 最长连续不下降子串
    时间复杂度:o(n)
    题解:输入a[1]到a[n]
    补上a[0]为负无穷大,a[n+1]为无穷大
    初始化k为1,ans为0
    然后一个一个a[i]扫下去 (1<=i<=n+1)
    如果a[i]<a[i-1],那么更新ans=max(ans,k); 
    否则k=k+1;
    最后ans就是答案
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1000000+10;
    const int INF=0x7FFFFFFF;
    int a[maxn],ans,k,n;
    
    void init()
    {
        for(int i=1; i<=n; i++) scanf("%d",&a[i]);
        a[0]=INF;a[n+1]=-INF;
    }
    
    void slove()
    {
        while(~scanf("%d",&n))
        {
            init();
            ans=0;
            k=1;
            for(int i=1; i<=n+1; i++)
            {
                if(a[i]<a[i-1])
                {
                    ans=max(ans,k);
                    k=1;
                }
                else k++;
            }
            printf("%d
    ",ans);
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2308: Lucky Number
    题解:设输入的n有x位,设Q等于10的x次方
    n*n最后的x位就是 (n*n)%Q
    那么只要判断 (n*n)%Q 和 n 是否相等就可以了
    要注意的一点就是 0<n<1e9
    n*n会超出int范围,所以用long long存储
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    long long n;
    long long _n;
    long long n2;
    int x;//n有x位
    
    void slove()
    {
        while(~scanf("%lld",&n))
        {
            _n=n; x=0;
            while(_n) x=x+1, _n=_n/10; //得到n有几位
            if((n*n)%((long long)pow(10.0,x))==n) printf("Yes
    ");
            else printf("No
    ");
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2309: 小明爱吃面
    时间复杂度:o(n)
    题解:一个简单的贪心题
    对于第i天,简单的说就是:是今天买,还是之前买?
    当然是要选择从第1天到当前天,价格最小的那一天买下今天所需的粮食。
    
    今天吃的价格其实就是之前那些天中最小的价格
    处理出每天的价格之后,求和即可。
    
    PS:语文不好...描述的可能不是很清楚。
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn=100000+10;
    int a[maxn],p[maxn];
    int n,ans;
    
    void init()
    {
        for(int i=1;i<=n;i++)
            scanf("%d%d",&a[i],&p[i]);
        ans=0;
    }
    
    void slove()
    {
        while(~scanf("%d",&n))
        {
            init();
    
            for(int i=2;i<=n;i++)
                p[i]=min(p[i-1],p[i]);//找出每一天的价格
    
            for(int i=1;i<=n;i++)
                ans=ans+a[i]*p[i];
    
            printf("%d
    ",ans);
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2310: 小明爱消除
    时间复杂度:o(n)
    题解:此题属于脑洞题,需要细细咀嚼
          (描述起来比较费劲,略)
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1000000+10;
    int tot[maxn*2];
    int ans,n;
    
    void init()
    {
        memset(tot,0,sizeof tot);
        ans=0;
    }
    
    void slove()
    {
        while(~scanf("%d",&n))
        {
            init();
            for(int i=1; i<=n; i++)
            {
                int x;
                scanf("%d",&x);
                tot[x]++;
            }
            int k=0,m;
            while(k<2*maxn)
            {
                m=tot[k]/2;
                tot[k]=tot[k]%2;
                tot[k+1]=tot[k+1]+m;
                k++;
            }
            for(int i=0; i<2*maxn; i++)
                ans=ans+tot[i];
            printf("%d
    ",ans);
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2311: 找数字
    时间复杂度:o(n*n)
    题解:开一个数组记录每个数字有几个
          tot[x]=y 代表x有y个!
          然后两层循环枚举B和C
          枚举到的时候 tot[B]--,tot[C]--;
          然后验证tot[B+C]是否大于0,即A是否存在
          大于零则表示存在。
          否则不存在。
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1000+10;
    int tot[maxn],a[maxn];
    int n;
    
    void slove()
    {
        while(~scanf("%d",&n))
        {
            memset(tot,0,sizeof tot);
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
                tot[a[i]]++;
            }
            int ans=0;
            for(int i=1; i<=n; i++)
            {
                for(int j=i+1; j<=n; j++)
                {
                    tot[a[i]]--;
                    tot[a[j]]--;
                    if(tot[a[i]+a[j]]>0)
                    {
                        ans=1;
                        break;
                    }
                    tot[a[i]]++;
                    tot[a[j]]++;
                }
                if(ans==1) break;
            }
            if(ans==0) printf("NO
    ");
            else printf("YES
    ");
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2312: 简单数学题
    题解:数学题,a的b次方和c的d次方都很大,直接判断是做不出来的。
    如果我们能找到一个函数F(x)是单调的,
    而F(X)的值又比较好算,那么可以通过比较F(X)的大小来判断自变量的大小。
    
    令F(X)=log(X),a的b次方和c的d次方当做自变量。
    那么接下来只要判断log(a的b次方)和log(c的d次方)的大小
    就可以判断a的b次方和c的d次方的大小了。
    
    而log(a的b次方)=b*log(a),log(c的d次方)=d*log(c),很容易计算。
    
    判断相等的时候注意一下精度问题。
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    double a,b,c,d;
    
    int main()
    {
        while(~scanf("%lf%lf%lf%lf",&a,&b,&c,&d))
        {
            double ans1=b*log(a);
            double ans2=d*log(c);
    
            if(fabs(ans1-ans2)<0.000001) printf("=
    ");
            else if(ans1>ans2) printf(">
    ");
            else printf("<
    ");
        }
        return 0;
    }
    /*
    ZUFE OJ 2313: 字符串还原
    时间复杂度:o(n)
    题解:水题,搞之...
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn=100+10;
    char s[maxn];
    int T;
    
    void slove()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",s);
            int len=strlen(s);
            for(int i=0;i<len;i++)
                if(i%2==0) printf("%c",s[i]);
            printf("
    ");
    
            for(int i=len-1;i>=0;i--)
                if(i%2==1) printf("%c",s[i]);
            printf("
    ");
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2314: 矩形周长
    时间复杂度:o(sqrt(n))
    题解:枚举一下边长就可以了
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int INF=0x7FFFFFFF;
    int T,n;
    
    void slove()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            int MaxL=sqrt(1.0*n);
            int ans=INF;
            for(int i=1;i<=MaxL;i++)
            {
                if(n%i!=0) continue;
                else
                {
                    if(2*(i+n/i)<ans)
                        ans=2*(i+n/i);
                }
            }
            printf("%d
    ",ans);
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2315: 小明的智力
    时间复杂度:o(n)
    题解:简单的贪心题
          先排序,然后吃2,最后吃1
          找到第一个比p大的位置
          从这个位置开始吃2,吃完2 最后吃1
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1000+10;
    int a[maxn];
    bool flag[maxn];
    int T,n,p;
    
    void slove()
    {
        scanf("%d",&T);
        while(T--)
        {
            memset(flag,0,sizeof flag);
            scanf("%d%d",&n,&p);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            sort(a+1,a+n+1);
            int now=n+1;
            for(int i=1;i<=n;i++)
            {
                if(a[i]>p)
                {
                    now=i;
                    break;
                }
            }
            
            for(int i=now;i<=n;i++)
                if(a[i]>p)
                    flag[i]=1,p=p+2;
    
            for(int i=1;i<=n;i++)
                if(flag[i]==0) p=p+1;
            printf("%d
    ",p);
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2316: 水题
    时间复杂度:o(n)
    题解:水题,搞之...
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int INF=0x7FFFFFFF;
    const int maxn=100000+10;
    int T,ans,n;
    int a[maxn];
    
    void slove()
    {
        scanf("%d",&T);
        while(T--)
        {
            ans=-INF;
            scanf("%d",&n);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            for(int i=2;i<=n;i++)
                if(a[i]-a[i-1]>ans)
                    ans=a[i]-a[i-1];
            printf("%d
    ",ans);
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2317:画个圈圈
    */
    #include<stdio.h>
    #include<math.h>
    #include<map>
    #include<algorithm>
    #include<string.h>
    using namespace std;
       
    const int maxn=10+10;
    int ans,N,M;
    char Map[maxn][maxn];
    bool flag[maxn][maxn];
    char sign;
    int dir[4][2]= {{-1,0},{1,0},{0,-1},{0,1}};
       
    void init()
    {
        memset(flag,0,sizeof flag);
        ans=0;
    }
       
    void dfs(int x,int y,int Dir)
    {
        if(flag[x][y]==1&&Dir!=-1)
        {
            ans=1;
            return;
        }
        flag[x][y]=1;
        for(int i=0; i<4; i++)
        {
            int NewX=x+dir[i][0];
            int NewY=y+dir[i][1];
       
            if(Dir==0&&i==1) continue;
            if(Dir==1&&i==0) continue;
            if(Dir==2&&i==3) continue;
            if(Dir==3&&i==2) continue;
            if(Map[NewX][NewY]!=sign) continue;
            if(NewX<0||NewX>=N) continue;
            if(NewY<0||NewY>=M) continue;
       
            dfs(NewX,NewY,i);
            if(ans) return;
        }
    }
       
    void slove()
    {
        while(~scanf("%d%d",&N,&M))
        {
            for(int i=0; i<N; i++)
                scanf("%s",Map[i]);
            init();
            for(int i=0; i<N; i++)
            {
                for(int j=0; j<M; j++)
                {
                    sign=Map[i][j];
                    memset(flag,0,sizeof flag);
                    dfs(i,j,-1);
                    if(ans) break;
                }
                if(ans) break;
            }
            if(ans==1) printf("Yes
    ");
            else printf("No
    ");
        }
    }
       
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2318: 跳格子
    时间复杂度:不会算
    题解:BFS
    */
    
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    
    const int INF=0x7FFFFFFF;
    int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    const int maxn=300+10;
    int N,M,ans;
    int Sx,Sy,Ex,Ey;
    int Map[maxn][maxn];
    int flag[maxn][maxn];
    struct Point
    {
        int x,y;
        int tot;
    };
    queue<Point>Q;
    
    void BFS()
    {
        while(!Q.empty()) Q.pop();
        for(int i=0;i<maxn;i++)
            for(int j=0;j<maxn;j++)
                flag[i][j]=INF;
        Point p;
        p.x=Sx; p.y=Sy; p.tot=0;
        Q.push(p);
        ans=-1;
        flag[Sx][Sy]=0;
        while(!Q.empty())
        {
            Point h=Q.front(); Q.pop();
            if(h.x==Ex&&h.y==Ey)
            {
                ans=h.tot;
                break;
            }
            for(int i=0;i<4;i++)
            {
                int NewX=h.x+dir[i][0];
                int NewY=h.y+dir[i][1];
    
                if(NewX>=1&&NewX<=N)
                {
                    if(NewY>=1&&NewY<=M)
                    {
                        if(Map[NewX][NewY]!=3)
                        {
                            if(flag[NewX][NewY]>h.tot+1)
                            {
                                flag[NewX][NewY]=h.tot+1;
                                Point x;
                                x.x=NewX;
                                x.y=NewY;
                                x.tot=h.tot+1;
                                Q.push(x);
                            }
                        }
                    }
                }
            }
        }
        printf("%d
    ",ans);
    }
    
    void slove()
    {
        while(~scanf("%d%d",&N,&M))
        {
            for(int i=1;i<=N;i++)
                for(int j=1;j<=M;j++)
                    scanf("%d",&Map[i][j]);
    
            for(int i=1;i<=N;i++)
                for(int j=1;j<=M;j++)
                {
                    if(Map[i][j]==1) Sx=i,Sy=j;
                    if(Map[i][j]==2) Ex=i,Ey=j;    
                }
    
            BFS();
        }
    }
    
    int main()
    {
        slove();
        return 0;
    }
    /*
    ZUFE OJ 2320: 高中几何没学好
    时间复杂度:o(1)
    题解:连接AX
          设三角形AFX面积为e,三角形AXE面积为f
          得到三个方程
          e+f=d
          f/c=(a+d)/(b+c)
          e/a=(c+d)/(a+b)
          三个未知量都可以解出来
    */
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    double a,b,c,k;
    double e,f;
    
    int main()
    {
        while(~scanf("%lf%lf%lf",&a,&b,&c))
        {
            k=(a+b)/(b+c);
            f=(a*c)/(b-c*k);
            e=k*f;
            printf("%.4lf
    ",e+f);
        }
        return 0;
    }
    /*
    ZUFE OJ 1606: 清洁公司
    题解:DFS求连通块
    */
    #include<stdio.h>
    
    char gird[105][105];
    int m,n;
    int dir[8][2]= {{-1,-1},{-1,0},{-1,1},{0,1}
        ,{1,1},{1,0},{1,-1},{0,-1}};
    
    void dfs(int x,int y)
    {
        int i,xx,yy;
        gird[x][y]='#';
        for(i=0; i<8; i++)
        {
            xx=x+dir[i][0];
            yy=y+dir[i][1];
            if(xx<0||yy<0||xx>=m||yy>=n) continue;
            if(gird[xx][yy]=='@') dfs(xx,yy);
        }
    }
    int main()
    {
        int i,j;
        int count;
        while( scanf("%d%d",&m,&n)!=EOF)
        {
            for(i=0; i<m; i++) scanf("%s",gird[i]);
            count=0;
            for(i=0; i<m; i++)
            {
                for(j=0; j<n; j++)
                {
                    if(gird[i][j]=='@')
                    {
                        dfs(i,j);
                        count++;
                    }
                }
            }
            printf("%d
    ",count);
        }
        return 0;
    }
    /*
    ZUFE OJ 2323: 黑鸡跑1000
    题解:水题..搞之..
    */
    #include <stdio.h>
    
    double a,b;
    
    int main()
    {
        while(~scanf("%lf%lf",&a,&b))
            printf("%.2lf
    ",500.0/a+500.0/b);
        return 0;
    }
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 进制转换
    数据备份服务商Rubrik获4000万美元B轮融资
    为QNetworkAccessManager添加超时提醒(自己记录一段时间里的下载字节数,用定时器去定期检测,从而判断是否超时)
    DIOCP3 DEMO的编译(去掉VCL前缀)
    Golang环境搭建,Notepad++配置Golang开发环境,Golang发送邮件
    川普当选对中国的好处在哪?(会注重实利,而不是虚的意识形态)
    带你走近AngularJS
    ASP.NET MVC学习之控制器篇扩展性
    微信语音识别及网页获取用户信息
    敏捷和自动化测试
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4941760.html
Copyright © 2011-2022 走看看