2018年天梯赛全国总决赛

 

2018年天梯赛全国总决赛

      

L1-049天梯赛座位分配2074327050.27
L1-050倒数第N个字符串15106322990.46
L1-051打折5227945900.50
L1-0522018我们要赢5229934510.67
L1-053电子汪10181029860.61
L1-054福到了1594531650.30
L1-055谁是赢家10130235180.37
L1-056猜数字20113435680.32

 

L2-025分而治之252626840.38
L2-026小字辈251966610.30
L2-027名人堂与代金券252266760.33
L2-028秀恩爱分得快251408310.17

 

L3-019代码排版3003170.00
L3-020至多删三个字符30652810.23
L3-021神坛301489970.15

 

题解(没有遵照题目集顺序):

L1-049天梯赛座位分配

(这题的难度应当是一阶梯中最难的了吧)

    先参考了一些大犇的写法:

#include<bits/stdc++.h>
using namespace std;
vector<int> m[105];
int sum=0;
struct node{
    vector<int>q;
    int num;
}a[105];
int main(){
   int n;
   cin>>n;
   int x;
   for(int i=1;i<=n;i++){
    cin>>x;
    a[i].num=x*10;
    sum+=x*10;//统计总人数
   }
   //cout<<sum<<endl;
   int id=1;
   while(sum--){
      for(int i=1;i<=n;i++){
        if(a[i].q.size()!=a[i].num){
            if(a[i].q.empty()==false&&a[i].q.back()+1==id){
                a[i].q.push_back(id+1);
                id+=2;
            }
            else{
               a[i].q.push_back(id);
               id++;
            }
        }
      }
   }
   for(int i=1;i<=n;i++){
      cout<<"#"<<i<<endl;
      for(int j=0;j<a[i].q.size();j++){
        if(j%10==0&&j!=0)
            cout<<endl;
        if(j%10!=0) cout<<" ";
        cout<<a[i].q[j];
      }
      cout<<endl;
   }
   return 0;
}

    这是众多写法中的一种, 其实这道模拟题第一眼看到也应该能明白是用数组解决,但是这不是一锤子买卖的问题,不要小瞧简单的数组——这背后的思维量是无穷无尽的。耗时很久我才稍稍明白大犇解决问题的思路。

   就是说:我们排座位,是需要按照队的数量、学校的数量排列的,而这两种排列标准也有优先大小(肯定是先排队再排学校了,如果说一个学校的排在一起肯定是不可以的TAT)。那么题目中这句话就显得格外重要:“如果最后只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐。“,也就是说这是一种特殊情况,那么我们在排序的时候,就按照这样的规律展开我们的代码:第一个学校的第一个队,插入第一个数;第二个学校的第二个队插入第二个数。。。

     

#1
1 4 7 10 13 16 19 22 25 28
31 34 37 40 43 46 49 52 55 58
61 63 65 67 69 71 73 75 77 79
#2
2 5 8 11 14 17 20 23 26 29
32 35 38 41 44 47 50 53 56 59
62 64 66 68 70 72 74 76 78 80
82 84 86 88 90 92 94 96 98 100
#3
3 6 9 12 15 18 21 24 27 30
33 36 39 42 45 48 51 54 57 60

也就是说,样例中除了#2中的第四行都是一般情况,只需要按照优先规则push_back就可以了。

对于特殊情况,为了造成隔一个位子的情况, 就要先检测末尾数+1是不是等于id,然后在插入的时候直接插入id+1,id自增2就可以喽。

L1-054福到了
#include<bits/stdc++.h>
using namespace std;
int main(){
    char ch;
    int n;
    cin>>ch>>n;
    getchar();
    int k=0,p=0;
    int j;
    int flag=1;
    char a[105][105],b[105][105],c[105][105];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
           scanf("%c",&a[i][j]);
           b[i][j]=a[i][j];
        }
        getchar();
    }
    for(int i=n-1;i>=0;i--){
        for(int j=n-1;j>=0;j--){
            if(b[k][p++]!=a[i][j])
                flag=0;
            c[i][j]=a[i][j];
        }
        p=0;
        k++;
    }
   if(flag){
    cout<<"bu yong dao le"<<endl;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(a[i][j]=='@')
            printf("%c",ch);
        else
            printf("%c",a[i][j]);
        }
        printf("\n");
    }
   }else{
       for(int i=n-1;i>=0;i--){
    for(int j=n-1;j>=0;j--){
        if(a[i][j]=='@')
            printf("%c",ch);
        else
            printf("%c",a[i][j]);
    }
    printf("\n");
    }


   }
   return 0;
}

 (当年觉得这题真的好难,现在看来的确是比较简单了,其实就是解决字符串的存储问题。在最开始思考的时候考虑最多的就是如何实现字符的替换,现在来看,只需要让有字符的按照规律输出制定字符,没有字符的位置按原图案输出就可以了)

L1-050倒数第N个字符串
#include<bits/stdc++.h>
using namespace std;
int main(){
    int l,n;
    cin>>l>>n;
    double X=pow((double)26,(double)l)-n;
    //cout<<X+n<<endl;
    int m=(int)X;
    //cout<<"m="<<m<<endl;
    char result[6];
    int i=0;
    for(int i=0;i<l;i++){
        result[i]='a'+m%26;
        m=m/=26;

    }
    for(int j=l-1;j>=0;j--)
    cout<<result[j];
}

这里,我们把字母当成数字进行处理。在给出的长度为l的字符串中,每一位都有26种选择,于是就是26的l次方种字符串。我们用这个数减去输入的int型数字,得到的就是正序数字,那么我们只需要实现数字到字符的转换就可以了。

L1-051打折

 

#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    int x,count;
    scanf("%d %d",&x,&count);
    double result=x*count*1.0/10;
    printf("%.2f\n",result);
    return 0;
}

 

L1-0522018我们要赢
#include<bits/stdc++.h>
using namespace std;
int main(){
    cout<<"2018"<<endl;
    cout<<"wo3 men2 yao4 ying2 !"<<endl;
}

 

L1-053电子汪
#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b;
    cin>>a>>b;
    int n=a+b;
    for(int i=1;i<=n;i++)
      cout<<"Wang!";
    cout<<endl;
}
L1-055谁是赢家

      这道题只需要把各种情况考虑清楚就可以了 

   

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int pa,pb;
    cin>>pa>>pb;
    int t;
    int a=0,b=0;
    for(int i=1; i<=3; i++)
    {
        cin>>t;
        if(t==0)
        {
            a++;
        }
        else
        {
            b++;
        }
    }

    //cout<<a<<" "<<b<<endl;
    if(pa>pb)
    {
        if(a>=1){
            printf("The winner is a: %d + %d",pa,a);
        }else{
            printf("The winner is b: %d + %d",pb,b);
        }
    }
    else if(pb>pa){
        if(b>=1){
            printf("The winner is b: %d + %d",pb,b);
        }
        else{
            printf("The winner is a: %d + %d",pa,a);
        }
    }
}
L1-056猜数字

 

#include<bits/stdc++.h>
using namespace std;
struct Node{
    string name;
    int num;
}node[10005];

int main(){
    int minx=99999;
    int sum=0;
    int n;
    cin>>n;
    string str;
    for(int i=0;i<n;i++){
        cin>>node[i].name>>node[i].num;
        sum+=node[i].num;
    }
    double result=sum*1.0/n/2;

    for(int i=0;i<n;i++){
        if(abs(node[i].num-result)<minx){
            minx=abs(node[i].num-result);
             str=node[i].name;
        }

    }
    cout<<(int)result<<" "<<str<<endl;
    return 0;
}

(排序都是多余的操作,其实只需要把各个人猜的数和平均数的一半进行比较,选择出差值最小的输出名字尽可以了)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值