zoukankan      html  css  js  c++  java
  • 哈理工多校算法赛一

    题目链接:https://www.nowcoder.com/acm/contest/67#question

    来源:牛客网

    A 吃鸡

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            int arr[n][1005];
            for(int i=0;i<n;i++)
            {
                scanf("%d%d",&arr[i][0],&arr[i][1]);
                for(int j=2;j<=1+arr[i][1];j++)
                    scanf("%d",&arr[i][j]);
            }
            int p,u=m; double brr[1005]={0},b,sum=0;
            while(m--)
            {
                scanf("%d",&p);
                scanf("%lf",&b);
                if(brr[p]==0) brr[p]=b;
                else brr[p]=max(b,brr[p]);
            }
            for(int i=0;i<n;i++)
            {
                double jc=1;
                for(int j=2;j<=1+arr[i][1];j++)
                    jc+=brr[arr[i][j]];
                sum=max(sum,arr[i][0]*jc);
            }
            printf("%.4f
    ",sum);
        }
        return 0;
    }
    View Code

    利用桶排序的思想存放配件加成值更方便

     

    B 游戏王

    #include <bits/stdc++.h>
    using namespace std;
    int value,sum;
    int arr[1005][3];
    stack<int> LS;
    void _one()
    {
        LS.pop();
        value+=LS.top();
    }
    void _two()
    {
        LS.pop();
        value+=sum*LS.top();
    }
    void _init()
    {
        while(!LS.empty())
            LS.pop();
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            value=0; sum=1; ///value记录伤害总值 sum记录栈内操作的个数
            int s,t;
            for(int i=0;i<n;i++)
            {
                scanf("%d%d",&arr[i][0],&arr[i][1]);
                if(arr[i][1]==1||arr[i][1]==2)
                    scanf("%d",&arr[i][2]);
            }   ///生成图 0~n-1 不包括n                                                  
    
            _init();  //初始化栈
            if(arr[0][1]==1||arr[0][1]==2)
                LS.push(arr[0][2]);   /* A:若为1 2操作 则将对应的x伤害值压入栈*/
            LS.push(arr[0][1]); 
    
            for(int i=1;i<=n;i++) /// 此时范围之所以包括n 
            {   /// 是因为最后一个操作(n-1)压入栈后
                /// 还需要进行连锁伤害操作
                if(arr[i][0]>=arr[i-1][0]&&i<n)//此处排除n的情况 因为不存在
                {
                    if(arr[i][1]==1||arr[i][1]==2)
                        LS.push(arr[i][2]);// 同A
                    LS.push(arr[i][1]);
                    sum++;     
                }   ///若发动速度符合 后者大于前者 的条件 则持续压入栈内
                if(arr[i][0]<arr[i-1][0]||i==n) ///一旦不符合条件 则开始连锁伤害
                {
                    while(!LS.empty())
                    {
                        if(LS.top()==1) _one();
                        else if(LS.top()==2) _two();
                        else if(LS.top()==3) _init();
                        else if(LS.top()==4)
                        {
                            LS.pop();
                            sum--;
                            if(!LS.empty()&&(LS.top()==1||LS.top()==2))
                                LS.pop(); 
                        } /* B:注意这里!一定要判断LS栈是否为空
                    再决定是否pop 因为之前出栈过 此时栈内可能为空 */
                        if(!LS.empty())
                        {
                            LS.pop(); /// 同B
                            sum--;
                        }
                    }   
                    ///此时操作完一套连锁 继续后面操作
                    if(arr[i][1]==1||arr[i][1]==2)
                        LS.push(arr[i][2]);   // 同A
                    LS.push(arr[i][1]);
                    sum=1;
                }
            }
            printf("%d
    ",value);
        }
        return 0;
    }
    View Code

     百度发现某位大佬的解法比我的更精简

    拜上链接 http://blog.csdn.net/deaidai/article/details/79124656

    C 六子冲

    #include <bits/stdc++.h>
    using namespace std;
    int a[5][5],x,y;
    int pd(int g)
    {
        if(g<=6&&g>=1) return 1;
        else return 0;
    }
    void up_dow()
    {
        if(x==1)
        {
            if(pd(a[x+1][y])==pd(a[x][y])&&pd(a[x+2][y])!=pd(a[x][y])
               &&!a[x+3][y]&&a[x+1][y]&&a[x+2][y])
                a[x+2][y]=0;
        }
        else if(x==2)
        {
            if(pd(a[x-1][y])==pd(a[x][y])&&pd(a[x+1][y])!=pd(a[x][y])
               &&!a[x+2][y]&&a[x-1][y]&&a[x+1][y])
                a[x+1][y]=0;
            else if(pd(a[x-1][y])!=pd(a[x][y])&&a[x+1][y]&&a[x-1][y]
               &&pd(a[x+1][y])==pd(a[x][y])&&!a[x+2][y])
                a[x-1][y]=0;
            else if(pd(a[x+2][y])!=pd(a[x][y])&&a[x+2][y]&&a[x+1][y]
               &&pd(a[x+1][y])==pd(a[x][y])&&!a[x-1][y])
                a[x+2][y]=0;
        }
        else if(x==3)
        {
            if(pd(a[x+1][y])==pd(a[x][y])&&a[x+1][y]&&a[x-1][y]
               &&pd(a[x-1][y])!=pd(a[x][y])&&!a[x-2][y])
                a[x-1][y]=0;
            else if(pd(a[x+1][y])!=pd(a[x][y])&&a[x+1][y]&&a[x-1][y]
               &&pd(a[x-1][y])==pd(a[x][y])&&!a[x-2][y])
                a[x+1][y]=0;
            else if(pd(a[x-2][y])!=pd(a[x][y])&&a[x-1][y]&&a[x-2][y]
               &&pd(a[x-1][y])==pd(a[x][y])&&!a[x+1][y])
                a[x-2][y]=0;
        }
        else
        {
            if(pd(a[x-1][y])==pd(a[x][y])&&a[x-1][y]&&a[x-2][y]
               &&pd(a[x-2][y]!=pd(a[x][y])&&!a[x-3][y]))
                a[x-2][y]=0;
        }
        return;
    }
    void le_rig()
    {
        if(y==1)
        {
            if(pd(a[x][y+1])==pd(a[x][y])&&a[x][y+2]&&a[x][y+1]
               &&pd(a[x][y+2])!=pd(a[x][y])&&!a[x][y+3])
                a[x][y+2]=0;
        }
        else if(y==2)
        {
            if(pd(a[x][y-1])==pd(a[x][y])&&a[x][y+1]&&a[x][y-1]
               &&pd(a[x][y+1])!=pd(a[x][y])&&!a[x][y+2])
                a[x][y+1]=0;
            else if(pd(a[x][y-1])!=pd(a[x][y])&&a[x][y-1]&&a[x][y+1]
                &&pd(a[x][y+1])==pd(a[x][y])&&!a[x][y+2])
                a[x][y-1]=0;
            else if(pd(a[x][y+2])!=pd(a[x][y])&&a[x][y+2]&&a[x][y+1]
                &&pd(a[x][y+1])==pd(a[x][y])&&!a[x][y-1])
                a[x][y+2]=0;
        }
        else if(y==3)
        {
            if(pd(a[x][y-1])==pd(a[x][y])&&a[x][y-1]&&a[x][y+1]
               &&pd(a[x][y+1])!=pd(a[x][y])&&!a[x][y-2])
                a[x][y+1]=0;
            else if(pd(a[x][y-1])==pd(a[x][y])&&a[x][y-2]&&a[x][y-1]
                &&pd(a[x][y-2])!=pd(a[x][y])&&!a[x][y+1])
                a[x][y-2]=0;
            else if(pd(a[x][y-1])!=pd(a[x][y])&&a[x][y+1]&&a[x][y-1]
                &&pd(a[x][y+1])==pd(a[x][y])&&!a[x][y-2])
                a[x][y-1]=0;
        }
        else
        {
            if(pd(a[x][y-1])==pd(a[x][y])&&a[x][y-1]&&a[x][y-2]
               &&pd(a[x][y-2])!=pd(a[x][y])&&!a[x][y-3])
                a[x][y-2]=0;
        }
        return;
    }
    int main()
    {
        int n,i=1;
        while(~scanf("%d",&n))
        {
            a[1][1]=11;a[1][2]=10;a[1][3]=9;a[1][4]=8;
            a[2][1]=12;a[2][2]= 0;a[2][3]=0;a[2][4]=7;
            a[3][1]= 1;a[3][2]= 0;a[3][3]=0;a[3][4]=6;
            a[4][1]= 2;a[4][2]= 3;a[4][3]=4;a[4][4]=5;
            while(n--)
            {
                int q,p; scanf("%d%d",&q,&p);
                for(x=1;x<=4;x++)
                {
                    for(y=1;y<=4;y++)
                        if(a[x][y]==q) break;
                    if(y<=4) break;
                }
                switch(p)
                {
                    case 1:
                        if(x>1)
                        { a[x][y]=a[x-1][y]; a[x-1][y]=q; x--; }
                        break;
                    case 2:
                        if(x<4)
                        { a[x][y]=a[x+1][y]; a[x+1][y]=q; x++; }
                        break;
                    case 3:
                        if(y>1)
                        { a[x][y]=a[x][y-1]; a[x][y-1]=q; y--; }
                        break;
                    case 4:
                        if(y<4)
                        { a[x][y]=a[x][y+1] ;a[x][y+1]=q; y++; }
                        break;
                }
                up_dow(); le_rig();
            }
            printf("#Case %d:
    ",i++);
            for(int k=1;k<=4;k++)
            {
                for(int j=1;j<=4;j++)
                    printf("%3d",a[k][j]);
                printf("
    ");
            }
        }
    
        return 0;
    }
    View Code

    不清楚差了些什么 只过了%20的样例

    题解http://blog.csdn.net/jaihk662/article/details/79121335

    D N阶汉诺塔

    网上某位大佬的思路 厉害 奈何看不懂代码

    https://www.cnblogs.com/widsom/p/8331657.html

    自己按思路写了一个 递归得出操作步骤存入数组 再根据数组内的操作步骤执行到第k步

    但没注意内存限制 根本开不下3^40的数组 卒

    #include <bits/stdc++.h>
    using namespace std;
    stack <int> A,B,C;
    int a[1000000],k,x;
    void sel(int i)
    {
        switch(i)
        {
            case 1: B.push(A.top());A.pop();break;
            case 2: C.push(B.top());B.pop();break;
            case 3: B.push(C.top());C.pop();break;
            case 4: A.push(B.top());B.pop();break;
        }
    }
    void ope(int j,int o)
    {
        if(j>k) return;
        int m=0;
        for(int i=1;i<=k/pow(3,o-1);i++)
        {
            if(i%3)
            {
                m++;
                a[j*i]= m%4 ? m%4 : 4 ;
            }
            else if(i==3) ope(j*i,o+1);
        }
    }
    void init()
    {
        while(!A.empty()) A.pop();
        while(!B.empty()) B.pop();
        while(!C.empty()) C.pop();
    }
    void print()
    {
        stack <int> a,b,c;
        while(!A.empty())
        { a.push(A.top()); A.pop(); }
        while(!B.empty())
        { b.push(B.top()); B.pop(); }
        while(!C.empty())
        { c.push(C.top()); C.pop(); }
    
        int fa=0,fb=0,fc=0;
        while(!a.empty())
        { printf("%d ",a.top()); a.pop(); fa=1; }
        if(!fa) printf("0"); printf("
    ");
        while(!b.empty())
        { printf("%d ",b.top()); b.pop(); fb=1; }
        if(!fb) printf("0"); printf("
    ");
        while(!c.empty())
        { printf("%d ",c.top()); c.pop(); fc=1; }
        if(!fc) printf("0"); printf("
    ");
    }
    int main()
    {
        int n;
        while(~scanf("%d%d",&n,&k))
        {
            init();
            for(int i=n;i>=1;i--)
                A.push(i);
            x=1;
            ope(1,1);
            for(int i=1;i<=k;i++)
                sel(a[i]);
            print();
        }
    
        return 0;
    }
    View Code

    另一份C/C++题解 http://blog.csdn.net/Jaihk662/article/details/79121367

    补:参透了大佬的代码 自己用栈做了一遍  但是不知道为什么还是过不了

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n,k;
        while(~scanf("%d%d",&n,&k))
        {
            stack <int> A,B,C;
            while(!A.empty()) A.pop();
            while(!B.empty()) B.pop();
            while(!C.empty()) C.pop();
     
            int m=1;
            for(int i=1;i<=n;i++)
            {
                int t=(k/m)%6;
                if(t>2) t=5-t;
                if(t==0) A.push(i);
                else if(t==1) B.push(i);
                else C.push(i);
                m*=3;
            }
     
            int fa,fb,fc; fa=fb=fc=0;
            while(!A.empty())
            {
                if(A.size()==1) printf("%d
    ",A.top());
                else printf("%d ",A.top());
                A.pop(); fa=1;
            }
            if(fa==0) printf("0
    ");
            while(!B.empty())
            {
                if(B.size()==1) printf("%d
    ",B.top());
                else printf("%d ",B.top());
                B.pop(); fb=1;
            }
            if(fb==0) printf("0
    ");
            while(!C.empty())
            {
                if(C.size()==1) printf("%d
    ",C.top());
                else printf("%d ",C.top());
                C.pop(); fc=1;
            }
            if(fc==0) printf("0
    ");
        }
     
        return 0;
    }
    View Code

    E 恋与程序员

    (SYS的代码)

    #include<bits/stdc++.h>
    using namespace std;
    int use[101],w[101][101],cost[101],n,m,k,t,ans=INT_MAX;
    ///use[]标记卡片是否买了,cost[]卡片的价格;w[](u,v矩阵),ans 最小花费; 
    int book[101]; void dfs(int o,int sum)
    {    
        if(o==t) ///找到了 这里的t是c即顶点数    
        {        
            ans=min(ans,sum);/*if (ans>sum) min=dis; return;*/        
            return;    
        }///令ans取最小值    
        for(int i=1;i<=n;i++)///遍历从1到C依次尝试       
        {           
            if(w[o][i]!=0)           
            {               
                if(use[w[o][i]]==0)               
                {                   
                    use[w[o][i]]=1;                   
                    dfs(i,sum+cost[w[o][i]]);///当前花费                   
                    use[w[o][i]]=0;///取消标记               
                }               
                else     dfs(i,sum);///直接遍历下一个点。           
            }         
            /*if(w[o][i]!=0&&book[i]==0) ///有通道        
            {            
                book[i]=1;            
                dfs(i,sum+cost[w[o][i]]);///当前花费;            
                book[i]=0;///取消标记        
            }            
            else    dfs(i,sum);*/                
        } 
    }
    int main ()    
    {    
        while(~scanf("%d%d%d%d",&n,&m,&k,&t)) 
        {        
            /*for(i=1;i<=n;i++)            
            for(j=1;j<=n;j++)            
            if(i==j)    w[i][j]=0;        
            else    w[i][j]=999999999;*/          
            memset(w,0,sizeof (w));///初始化赋值为零        
            ans=INT_MAX;///c++中通过设置INT_MAX便于比较最大值或者最小值!        
            for(int i=1,u,v,z;i<=m;i++) 
            {            
                scanf("%d%d%d",&u,&v,&z);            
                w[u][v]=z;///单向图!        
            }        
            for(int i=1,x,y;i<=k;i++) 
            {            
                scanf("%d%d",&x,&y);            
                cost[x]=y;///x卡片的价格,通过数组便于找到下标!!        
            }        ///book[1]=1;        
            dfs(1,0);///表示当前城市的编号,0表示已走过的路程。        
            printf("%d
    ",ans);    
        }
    } 
    /*
    6 7 5 6
    2 3 2
    4 3 3
    1 2 1
    1 5 4
    4 6 5
    1 4 2
    5 6 3
    1 100
    3 422
    2 210
    5 107
    4 38
    */
        
    View Code

    自己做了一遍

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,k,c,ans;
    int a[105][105],price[1005],used[1005];
    void DFS(int i,int sum)
    {
        if(i==c)
        {
            ans=min(sum,ans);
            return;
        }
        for(int j=2;j<=n;j++)
        {
            if(a[i][j])
                if(!used[a[i][j]])
                {
                    used[a[i][j]]=1;
                    DFS(j,sum+price[a[i][j]]);
                    used[a[i][j]]=0;
                }
            else DFS(j,sum);
        }
    }
    int main()
    {
        while(~scanf("%d%d%d%d",&n,&m,&k,&c))
        {
            ans=1e9;
            memset(a,0,sizeof(a));
            memset(price,0,sizeof(price));
            memset(used,0,sizeof(used));
            while(m--)
            {
                int u,v,e;
                scanf("%d%d%d",&u,&v,&e);
                a[u][v]=e;
            }
            while(k--)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                price[a]=b;
            }
            DFS(1,0);
            printf("%d
    ",ans);
        }
     
        return 0;
    }
    View Code

    F 跑毒

    #include <bits/stdc++.h>
    int main()
    {
        int t; scanf("%d",&t);
        while(t--)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            int dis=0,blood=100;
            while(c>0&&dis<b)
            {
                while(blood>6*a)
                {
                    blood-=a;
                    dis++;
                }
                dis--;
                c--;
                blood=80;
            }
            if((b-dis-1)*a<80) printf("YES
    ");
            else printf("NO
    ");
        }
     
        return 0;
    }
    View Code

    G 圆圈

    #include <bits/stdc++.h>
    using namespace std;
    char a[7000][7000];
    int power[10];
    void change(int n,int i,int j)
    {
        if(n==0)
        {
            a[i][j]='O';
            return;
        }
        else
        {
            int m=power[n-1];
            change(n-1,i,j+m);
            change(n-1,i+m,j);change(n-1,i+m,j+2*m);
            change(n-1,i+2*m,j+m);
        }
    }
    int main()
    {
        int t; scanf("%d",&t);
        power[0]=1;
        for(int i=1;i<=8;i++)
            power[i]=power[i-1]*3;
        while(t--)
        {
            int n; scanf("%d",&n);
            for(int i=0;i<power[n];i++)
                for(int j=0;j<power[n];j++)
                    a[i][j]=' ';
            change(n,0,0);
            for(int i=power[n]-1;i>=0;i--)
            {
                for(int j=power[n]-1;j>=0;j--)
                    if(a[i][j]=='O')
                    {
                        a[i][j+1]='';
                        break;
                    }
            }
            for(int i=0;i<power[n];i++)
            {
                for(int j=0;a[i][j]!='';j++)
                    printf("%c",a[i][j]);
                printf("
    ");
            }
        }
     
        return 0;
    }
    View Code

    H 方块与收纳盒

    斐波那契数列 只要想清楚这点 

    N的情况 是 (N-1的所有情况加一个1*1的方块) 和 (N-2的所有情况加一个1*2的方块) 的总和

    I 找数字个数

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int t; scanf("%d",&t);
        while(t--)
        {
            int flag[10],cnt=0;
            memset(flag,0,sizeof(flag));
            int a,b; scanf("%d%d",&a,&b);
            int m,n; m=a,n=b;
            while(m)
            {
                flag[m%10]=1;
                m/=10;
            }
            while(n)
            {
                flag[n%10]=1;
                n/=10;
            }
            for(int num=1;num<=1000;num++)
            {
                if(num%a==0||num%b==0) continue;
                int j=num;
                while(j)
                {
                    if(flag[j%10]==1) break;
                    j/=10;
                }
                if(j) continue;
                cnt++;
            }
            printf("%d
    ",cnt);
        }
     
        return 0;
    }
    View Code

    J 闯关的lulu

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int t; scanf("%d",&t);
            while(t--)
            {
                int n,c=0; scanf("%d",&n);
                int ans[10];
                memset(ans,0,sizeof(ans));
                n=n+(n/2)*2;
                while(n)
                {
                    if(n%(c+2)==0) ans[c]=0;
                    else
                    {
                        ans[c]=n%(c+2);
                        ans[c+1]=n/(c+2);
                    }
                    n/=(c+2);
                    c++;
                }
                for(int i=c;i>=0;i--)
                {
                    for(int j=0;j<ans[i];j++)
                        printf("%d",i);
                }
                printf("
    ");
            }
     
        return 0;
    }
    View Code

    思路来自 http://blog.csdn.net/qq_40644471/article/details/79130220

    以后请一定记住

    打比赛不要死磕一道题

  • 相关阅读:
    2020/10/25助教一周小结(第八周)
    2020/10/18助教一周小结(第七周)
    2020/10/11助教一周小结(第六周)
    2020/10/05助教一周小结(第五周)
    2020/09/27助教一周小结(第四周)
    第三次作业总结
    第二次作业总结
    2020-11-08 助教一周小结(第十周)
    2020-11-01 助教一周小结(第九周)
    2020-10-25 助教一周小结(第八周)
  • 原文地址:https://www.cnblogs.com/zquzjx/p/8331365.html
Copyright © 2011-2022 走看看