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

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

$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\n",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]=='\0') printf(" ");
        else
        {
            printf("%c",m[n][i]);
            break;
        }
    }
    printf("\n");

    for(int i=2; i<=n-1; i++)
    {
        int g=0;
        for(int j=1;; j++)
        {
            if(m[i][j]=='\0') printf(" ");
            else
            {
                g++;
                printf("%c",m[i][j]);
                if(g==2) { printf("\n"); break; }
            }
        }
    }

    for(int i=1;; i++)
    {
        if(m[n][i]=='\0') printf(" ");
        else
        {
            printf("%c",m[n][i]);
            break;
        }
    }
    printf("\n");

    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\n",a,b,a+b);
    printf("%d - %d = %d\n",a,b,a-b);
    printf("%d * %d = %d\n",a,b,a*b);
    if(a%b!=0) 
        printf("%d / %d = %.2f\n",a,b,1.0*a/b);
    else 
        printf("%d / %d = %d\n",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.\n"); return 0;}
    
    printf("fahr celsius\n");
    
    for(int i=a;i<=b;i=i+2)
    {
        printf("%d%6.1f\n",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\n",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\n",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\n");
    if(x==1) printf("/*-?\n");
    if(x==2) printf("(-?\n");
    if(x==3) printf("[-?\n");
    if(x==4) printf("{-?\n");
}

void OUT(int x)
{
    printf("NO\n");
    if(x==1) printf("?-*/\n");
    if(x==2) printf("?-)\n");
    if(x==3) printf("?-]\n");
    if(x==4) printf("?-}\n");
}

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\n");
    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\n",A);
    else if(a[B]==0) printf("ERROR: T[%d] is NULL\n",B);
    else 
    {
        while(1)
        {
            if(A==B) break;
            if(A>B) A=A/2;
            else B=B/2;
        }

        printf("%d %d\n",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\n",sum);

    for(int i=1;i<=k;i++)
    {
        printf("%d",ckans[i]);
        if(i<k) printf(" ");
    }
    printf("\n");

    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\n",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\n",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\n");
            else printf("No\n");
        }
    }
    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\n",ans);
    else printf("Impossible\n");


    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\n",a[(2*n+1)/2]);

    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/zufezzt/p/6494083.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值