哈理工多校算法赛一

题目链接: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

以后请一定记住

打比赛不要死磕一道题

原文地址:https://www.cnblogs.com/zquzjx/p/8331365.html