• 浙江财经大学天梯赛选拔赛题解


    现场写的代码,比较乱.....

    $1$.[分值:$5$] $5-11$ 编程打印空心字符菱形

    模拟一下下即可

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    char s[5];
    char m[500][500];
    int r ,c ,x,n;
    
    int main()
    {
        cin>>s>>n;
        char now=s[0];
    
        if(n==1)
        {
            printf("%c
    ",now);
            return 0;
        }
    
        r =1, c=n/2+1, x=n/2+1;
        while(x--) m[r][c]=now, now++, r++, c--;
    
        now=s[0], r=1, c=n/2+1, x=n/2+1;
        while(x--) m[r][c]=now, now++, r++, c++;
    
    
        now=s[0],r=n, c=n/2+1,x=n/2+1;
        while(x--) m[r][c]=now,now++, r--, c--;
    
        now=s[0],r=n, c=n/2+1,x=n/2+1;
        while(x--) m[r][c]=now,now++,r--, c++;
    
        for(int i=1;; i++)
        {
            if(m[1][i]=='') printf(" ");
            else
            {
                printf("%c",m[n][i]);
                break;
            }
        }
        printf("
    ");
    
        for(int i=2; i<=n-1; i++)
        {
            int g=0;
            for(int j=1;; j++)
            {
                if(m[i][j]=='') printf(" ");
                else
                {
                    g++;
                    printf("%c",m[i][j]);
                    if(g==2) { printf("
    "); break; }
                }
            }
        }
    
        for(int i=1;; i++)
        {
            if(m[n][i]=='') printf(" ");
            else
            {
                printf("%c",m[n][i]);
                break;
            }
        }
        printf("
    ");
    
        return 0;
    }
    View Code

    $2$.[分值:$5$] $5-17$ 算术入门之加减乘除

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int a,b;
    
    int main()
    {
        cin>>a>>b;
        printf("%d + %d = %d
    ",a,b,a+b);
        printf("%d - %d = %d
    ",a,b,a-b);
        printf("%d * %d = %d
    ",a,b,a*b);
        if(a%b!=0) 
            printf("%d / %d = %.2f
    ",a,b,1.0*a/b);
        else 
            printf("%d / %d = %d
    ",a,b,a/b);
    
        return 0;
    }
    View Code

    $3$.[分值:$10$] $5-9$ 输出华氏-摄氏温度转换表

    注意输出格式

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int a,b;
    
    int main()
    {
        cin>>a>>b;
        if(a>b) { printf("Invalid.
    "); return 0;}
        
        printf("fahr celsius
    ");
        
        for(int i=a;i<=b;i=i+2)
        {
            printf("%d%6.1f
    ",i,5.0*(i-32)/9);
        }
        return 0;
    }
    View Code

    $4$.[分值:$10$] $5-14$ 掉入陷阱的数字

    模拟。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int n;
    int f[100000];
    
    int get(int x)
    {
        int sum=0;
        while(x)
        {
            sum=sum+x%10;
            x=x/10;
        }
        return sum*3+1;
    }
    
    int main()
    {
        cin>>n;
        int now=n; f[now]++;
        for(int i=1;;i++)
        {
            now=get(now);
            f[now]++;
            printf("%d:%d
    ",i,now);
            if(f[now]==2) break;
        }
    
        return 0;
    }
    View Code

    $5$.[分值:$15$] $5-8$ 人民币兑换

    暴力枚举

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int n;
    
    int main()
    {
        cin>>n; int ans=0;
        for(int i=1;i<=100;i++)
        {
            for(int j=1;j<=100;j++)
            {
                for(int k=1;k<=100;k++)
                {
                    if(5*i+2*j+1*k==5*1+2*46+1*53&&i+j+k==100)
                    {
                        printf("%d %d %d
    ",i,j,k);
                        ans++;
                        if(ans==n) return 0;
                    }
                }
            }
        }
    
        return 0;
    }
    View Code

    $6$.[分值:$15$] $5-18$ 大炮打蚊子

    模拟,注意出界的判断

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    char s[500][500];
    int n,m;
    int f[500][500];
    
    bool check(int a,int b)
    {
        if(a>=0&&a<n&&b>=0&&b<m) return 1;
        return 0;
    }
    
    int main()
    {
        cin>>n>>m;
        for(int i=0;i<n;i++) cin>>s[i];
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(s[i][j]=='#') f[i][j]=2;
            }
        }
        int q;
        cin>>q;
        while(q--)
        {
            int x,y,ans=0;
            cin>>x>>y;
            if(f[x][y]) ans++, f[x][y]=0;
    
            if(check(x-1,y)&&f[x-1][y]) 
            {
                f[x-1][y]--;
                if(f[x-1][y]==0) ans++;
            }
    
            if(check(x+1,y)&&f[x+1][y]) 
            {
                f[x+1][y]--;
                if(f[x+1][y]==0) ans++;
            }
    
            if(check(x,y-1)&&f[x][y-1]) 
            {
                f[x][y-1]--;
                if(f[x][y-1]==0) ans++;
            }
    
            if(check(x,y+1)&&f[x][y+1]) 
            {
                f[x][y+1]--;
                if(f[x][y+1]==0) ans++;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    $7$.[分值:$20$] $5-2$ 符号配对

    栈。

    遇到左括号,压入栈。

    遇到右括号   ($1$)如果栈为空那么这个有括号没有左括号与他配对

          ($2$) 如果栈顶和这个有括号配对,弹出栈顶

          ($3$)如果栈顶不和这个有括号配对,那么栈顶就是没有右括号和他匹配了

    最后如果栈为空,那么输出$YES$;否则还是需要输出栈顶没有右括号和他匹配

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    char s[100000];
    
    stack<int>st;
    
    void out(int x)
    {
        printf("NO
    ");
        if(x==1) printf("/*-?
    ");
        if(x==2) printf("(-?
    ");
        if(x==3) printf("[-?
    ");
        if(x==4) printf("{-?
    ");
    }
    
    void OUT(int x)
    {
        printf("NO
    ");
        if(x==1) printf("?-*/
    ");
        if(x==2) printf("?-)
    ");
        if(x==3) printf("?-]
    ");
        if(x==4) printf("?-}
    ");
    }
    
    int main()
    {
        int fail=0;
        while(cin>>s)
        {
            int len=strlen(s);
            if(s[0]=='.'&&len==1) break;
    
            if(fail) break;
    
            for(int i=0;i<len;)
            {
                if(s[i]=='/'&&s[i+1]=='*')
                {
                    st.push(1);
                    i=i+2;
                }
                else if(s[i]=='*'&&s[i+1]=='/')
                {
                    if(st.empty()||st.top()!=1)
                    {
                        if(st.empty()) OUT(1);
                        else out(st.top());
                        return 0;
                    }
                    else st.pop();
    
                    i=i+2;
                }
    
                else if(s[i]=='(')
                {
                    st.push(2);
                    i=i+1;
                }
                else if(s[i]==')')
                {
                    if(st.empty()||st.top()!=2)
                    {
                        if(st.empty()) OUT(2);
                        else out(st.top());
                        return 0;
                    }
                    else st.pop();
    
                    i=i+1;
                }
    
                else if(s[i]=='[')
                {
                    st.push(3);
                    i=i+1;
                }
                else if(s[i]==']')
                {
                    if(st.empty()||st.top()!=3)
                    {
                        if(st.empty()) OUT(3);
                        else out(st.top());
                        return 0;
                    }
                    else st.pop();
    
                    i=i+1;
                }
    
                else if(s[i]=='{')
                {
                    st.push(4);
                    i=i+1;
                }
                else if(s[i]=='}')
                {
                    if(st.empty()||st.top()!=4)
                    {
                        if(st.empty()) OUT(4);
                        else out(st.top());
                        return 0;
                    }
                    else st.pop();
    
                    i=i+1;
                }
                else i++;
            }
        }
    
        if(st.empty()) printf("YES
    ");
        else out(st.top());
    
        return 0;
    }
    View Code

    $8$.[分值:$20$] $5-10$ 说反话-加强版

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    vector<string>v;
    
    int main()
    {
        string s; int sz=0;
        while(cin>>s)
        {
            sz++;
            v.push_back(s);
        }
    
        for(int i=sz-1;i>=0;i--)
        {
            cout<<v[i];
            if(i>0) cout<<" ";
            else cout<<endl;
        }
    
    }
    View Code

    $9$.[分值:$25$] $5-3$ 顺序存储的二叉树的最近的公共祖先问题

    用数组存二叉树,节点$p$的左儿子为$2*p$,右儿子为$2*p+1$。某节点要往父亲节点走,只要节点编号$/2$即可。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int n,a[2000];
    int A,B;
    
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        cin>>A>>B;
    
        if(a[A]==0) printf("ERROR: T[%d] is NULL
    ",A);
        else if(a[B]==0) printf("ERROR: T[%d] is NULL
    ",B);
        else 
        {
            while(1)
            {
                if(A==B) break;
                if(A>B) A=A/2;
                else B=B/2;
            }
    
            printf("%d %d
    ",A,a[A]);
        }
    
        return 0;
    }
    View Code

    $10$.[分值:$25$] $5-4$ 银行排队问题之单队列多窗口服务

    模拟,记录一下每个窗口最早空闲的时间即可。最后一组数据大概是错误的。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int n,k;
    struct P
    {
        int daoda;
        int jieshou;
        int chuli;
        int likai;
    }p[2000];
    
    int cklast[30];
    int ckans[30];
    
    int main()
    {
        memset(cklast,0,sizeof cklast);
        memset(ckans,0,sizeof ckans);
    
        scanf("%d",&n);
    
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].daoda,&p[i].chuli);
            p[i].chuli = min(60,p[i].chuli);
        }
        scanf("%d",&k);
    
        for(int i=1;i<=n;i++)
        {
            int idx, Find=0; int mn=0x3f3f3f3f;
            for(int j=1;j<=k;j++)
            {
                if(cklast[j]<p[i].daoda) // if(cklast[j]<=p[i].daoda)讲道理是要有等号的,但是加了就错
                {
                    p[i].jieshou = p[i].daoda;
                    p[i].likai = p[i].jieshou + p[i].chuli;
                    ckans[j]++;
                    cklast[j] = p[i].likai;
                    Find=1;
                    break;
                }
            }
    
            if(Find==0)
            {
                for(int j=1;j<=k;j++)
                {
                    if(cklast[j]<mn)
                    {
                        mn=cklast[j];
                        idx=j;
                    }
                }
    
                p[i].jieshou = mn;
                p[i].likai = p[i].jieshou + p[i].chuli;
                ckans[idx]++;
                cklast[idx] = p[i].likai;
            }
        }
    
        int sum=0;
        for(int i=1;i<=n;i++) sum=sum+p[i].jieshou-p[i].daoda;
        printf("%.1lf ",1.0*sum/n);
    
        sum=0;
        for(int i=1;i<=n;i++) sum=max(sum,p[i].jieshou-p[i].daoda);
        printf("%d ",sum);
    
        sum=0;
        for(int i=1;i<=n;i++) sum=max(sum,p[i].likai);
        printf("%d
    ",sum);
    
        for(int i=1;i<=k;i++)
        {
            printf("%d",ckans[i]);
            if(i<k) printf(" ");
        }
        printf("
    ");
    
        return 0;
    }
    View Code

    $11$.[分值:$25$] $5-7$ 城市间紧急救援

    最短路,拓扑排序上$dp$。

    为了避免写一发最短路上繁琐的$if$判断,我个人比较喜欢先处理出一个只包含最短路的有向无环图。然后在这个有向无环图上用拓扑排序搞$dp$就可以了。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int INF=0x7FFFFFFF;
    int n,m,s,d;
    int v[1000];
    
    struct Edge
    {
        int a,b,c;
    }e[300000];
    int sz;
    vector<int>g[1000],t[1000];
    int f[1000],disS[1000],disD[1000],pre[1000],GET[1000],in[1000],p[1000];
    
    void add(int A,int B,int C)
    {
        e[sz].a=A; e[sz].b=B; e[sz].c=C;
        g[e[sz].a].push_back(sz); sz++;
    }
    
    void spfaS()
    {
        queue<int>Q; 
        for(int i=0;i<n;i++) f[i]=0,disS[i]=INF;
        disS[s]=0; Q.push(s); f[s]=1;
    
        while(!Q.empty())
        {
            int h=Q.front(); Q.pop(); f[h]=0;
    
            for(int i=0;i<g[h].size();i++)
            {
                int id = g[h][i];
    
                if(disS[h]+e[id].c<disS[e[id].b])
                {
                    disS[e[id].b]=disS[h]+e[id].c;
                    if(f[e[id].b]==0)
                    {
                        Q.push(e[id].b);
                        f[e[id].b]=1;
                    }
                }
            }
        }
    }
    
    void spfaD()
    {
        queue<int>Q; 
        for(int i=0;i<n;i++) f[i]=0,disD[i]=INF;
        disD[d]=0; Q.push(d); f[d]=1;
    
        while(!Q.empty())
        {
            int h=Q.front(); Q.pop(); f[h]=0;
    
            for(int i=0;i<g[h].size();i++)
            {
                int id = g[h][i];
    
                if(disD[h]+e[id].c<disD[e[id].b])
                {
                    disD[e[id].b]=disD[h]+e[id].c;
                    if(f[e[id].b]==0)
                    {
                        Q.push(e[id].b);
                        f[e[id].b]=1;
                    }
                }
            }
        }
    }
    
    void W()
    {
        queue<int>Q;
        Q.push(s); GET[s]=v[s]; p[s]=1;
        while(!Q.empty())
        {
            int h=Q.front(); Q.pop();
            for(int i=0;i<t[h].size();i++)
            {
                int to = t[h][i];
                p[to]=p[to]+p[h]; in[to]--;
    
                if(GET[h]+v[to]>GET[to])
                {
                    GET[to]=GET[h]+v[to];
                    pre[to]=h;
                }
                if(in[to]==0) Q.push(to);
            }
        }
    }
    
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&s,&d);
        for(int i=0;i<n;i++) cin>>v[i];
        for(int i=1;i<=m;i++) 
        {
            int A,B,C; cin>>A>>B>>C;
            add(A,B,C); add(B,A,C);
        }
    
        spfaS();
        spfaD();
    
    
        for(int i=0;i<sz;i++)
        {
            if(disS[e[i].a]+disD[e[i].b]+e[i].c == disS[d])
            {
                t[e[i].a].push_back(e[i].b);
                in[e[i].b]++;
            }
        }
    
        memset(pre,-1,sizeof pre);
    
        W();
    
        printf("%d %d
    ",p[d],GET[d]);
    
        stack<int>st;
    
        int now=d;
        
        while(1)
        {
            if(now==-1) break;
            st.push(now);
            now=pre[now];
        }
    
        vector<int>ans;
    
        while(!st.empty())
        {
            ans.push_back(st.top());
            st.pop();
        }
    
        for(int i=0;i<ans.size();i++)
        {
            if(i<ans.size()-1) printf("%d ",ans[i]);
            else printf("%d
    ",ans[i]);
        }
    
        return 0;
    }
    View Code

    $12$.[分值:$25$] $5-13$ 是否同一棵二叉搜索树

    开两个数组存树,然后比较数组是否相同即可。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int n,m;
    
    int s[2][20000];
    
    void Insert(int x,int y)
    {
        int p=1;
        while(1)
        {
            if(y<s[x][p])
            {
                if(s[x][2*p]==-1) 
                {
                    s[x][2*p]=y;
                    break;
                }
                else p=2*p;
            }
            else 
            {
                if(s[x][2*p+1]==-1) 
                {
                    s[x][2*p+1]=y;
                    break;
                }
                else p=2*p+1;
            }
        }
    }
    
    bool check()
    {
        for(int i=1;i<10000;i++)
        {
            if(s[0][i]!=s[1][i]) return 0;
        }
        return 1;
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            if(n==0) break;
    
            cin>>m;
    
            memset(s,-1,sizeof s);
    
            int x; cin>>x; s[0][1]=x;
            for(int i=2;i<=n;i++)
            {
                int x; cin>>x;
                Insert(0,x);
            }
    
            while(m--)
            {
                for(int i=0;i<10000;i++) s[1][i]=-1;
                cin>>x; s[1][1]=x;
                for(int i=2;i<=n;i++)
                {
                    int x; cin>>x;
                    Insert(1,x);
                }
    
                if(check()) printf("Yes
    ");
                else printf("No
    ");
            }
        }
        return 0;
    }
    View Code

    $13$.[分值:$30$] $5-5$ 银行排队问题之单队列多窗口加$VIP$服务

    这题还没写,但是之前写过一个和这题类似的模拟题,较为恶心。1026. Table Tennis (30),我的代码在这里

    $14$.[分值:$30$] $5-6$ 畅通工程之最低成本建设问题

    最小生成树。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int n,m;
    int f[2000];
    struct Edge
    {
        int a,b,c;
    }e[100000];
    
    bool cmp(Edge a,Edge b)
    {
        return a.c<b.c;
    }
    
    int Find(int x)
    {
        if(f[x]!=x) return f[x]=Find(f[x]);
        return f[x];
    }
    
    int main()
    {
        
        
        scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) f[i]=i;
    
        for(int i=1;i<=m;i++)
        {
            cin>>e[i].a>>e[i].b>>e[i].c;
        }
    
        sort(e+1,e+1+m,cmp);
    
        int sz=n,ans=0;
    
        for(int i=1;i<=m;i++)
        {
            int A=Find(e[i].a);
            int B=Find(e[i].b);
    
            if(A==B) continue;
    
            sz--;
            ans=ans+e[i].c;
            f[A]=B;
        }
    
        if(sz==1) printf("%d
    ",ans);
        else printf("Impossible
    ");
    
    
        return 0;
    }
    View Code

    $15$.[分值:$30$] $5-19$ 两个有序序列的中位数

    因为两个序列都是有序的,可以$O(n)$效率排序,但是他居然数据范围不是$100$万或者$1000$万,没有卡快排。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int n;
    int a[200010],b[100010];
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=n+1;i<=n+n;i++) scanf("%d",&a[i]);
    
        sort(a+1,a+1+2*n);
        printf("%d
    ",a[(2*n+1)/2]);
    
        return 0;
    }
    View Code
  • 相关阅读:
    2所非211院校挺进全球高校600强,甩开一众985 | 泰晤士世界大学排行榜出炉
    深度强化学习专栏(三)
    PyTorch专栏(八):微调基于torchvision 0.3的目标检测模型
    PyTorch专栏(六): 混合前端的seq2seq模型部署
    3分钟了解GPT Bert与XLNet的差异
    PyTorch专栏(五):迁移学习
    NLPer,你知道最近很火的自然语言处理库么?
    E
    网络流 I
    D
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6494083.html
Copyright © 2020-2023  润新知