CSP-X模拟赛——葛小伟补题

日期:10月1日
学号:4dd03f
一、总分数
总分数:10
T1【爬楼梯(stair)】:10
T2【字符折线图(sline)】:0
T3【吉利数(lucknum)】:0
T4【路灯照明(lighting)】:0
二、比赛过程
第一题比较简单,但是漏了一点:记录的是每一步迈出去的距离能够跨越多少个台阶,比如还剩一个台阶就能到达下一个平台,她步子迈的再大,也只能上一个台阶。不存在一步跨越好几个平台的情况。
第二题难度提升了,要考虑很多可能性,如字符位置、多余空格等。最后百密一疏(漏了\),只得了0分。
第三题半斤八两,最可怕的是有19位数(真实与9进制有关,实在想不到)。最后靠枚举扳回一局,得了0分。
第四题难度可以说是第三题的100倍(还是用枚举法得了0分)。
三、比赛分析
T1【爬楼梯(stair)】:
1.题目大意
有人不打算坐电梯,于是他们打算爬楼梯爬上来!他从第一层出发,记录了每一步迈出去的距离能够跨越多少个台阶及迈多少个台阶能够到达下一个平台。
和很多大楼类似,每次爬楼梯到达一个平台,就需要转身再爬,到达两个平台代表上了一层楼。
请你计算一下,现在他已经到达了多少层!
2、比赛中的思考
我用的是for循环遍历,但没有记录正确的上楼代码,只是恰好对了一个样例,得了10分。
3、解题思路
将每次走得进行累加,注意每次爬楼梯到达一个平台,就需要转身再爬,这一步中断了,并且到达两个平台才代表上了一层楼。
4、AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,x,tmp,sum,cnt;
int main(){
    scanf("%d%d",&n,&x);
    for(int i=1;i<=n;i++){
    scanf("%d",&tmp);
    if(sum+tmp>=x){
        sum=0;
        cnt++;
    }else{
        sum+=tmp;
    }
    printf("%d\n",1+int(cnt/2));
    return 0;
}
T2 T2【字符折线图(sline)】:
1.题目大意
字符串也是有起伏的!我们根据一个字符串,可以画出一个折线图。从第二个字符开始,如果它比它的上一个字符大,那么就是上升的,画一个/;如果和上一个字符相同,那么画一个-;如果比比上一个字符小,那么就是下降的,画一个\。并且上升的时候,要向上一行,下降的时候向下一行。
2、比赛中的思考
开局以为与第一题一样简单,后来才发现要去空格,不会。
3、解题思路
在输入完后判断字符的ASCLL码大小,并注意字符位置。如果大,输出一个'/',下次输出时放在右上方;如果小,输出一个'\\',下次输出时放在右下方;如果相等,输出一个'-',下次输出时放在右方。最后输出时,去掉多余空格即可。
4、AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
char s[105];
int g[405][405];
int main(){
    scanf("%s",s);
    int n=strlen(s),line=200,pre=0;
    for(int i=1;i<n;i++){
        if(s[i]==s[i-1]){
            if(pre==2){
                line++;
            }else if(pre==3){
                line--;
            } 
        g[line][i]=pre=1;
        }else if(s[i-1]<s[i]){
            if(pre!=3){
                line++;
            } 
        g[line][i]=pre=2;
        }else{
            if(pre!=2){
                line--;
            } 
            g[line][i]=pre=3;
        }
    }
    for(int i=0;i<405;i++){
        for(int j=204;j>0;j--){
            if(g[i][j]){
                    g[i][0]=j;
                break;
            }
        }
    }
    int bg=404,ends=0;
    while(!g[bg][0]){
        bg--;
    } 
    while(!g[ends][0]){
        ends++;
    } 
    for(int i=bg;i>=ends;i--){
        for(int j=1;j<=g[i][0];j++){
            if(!g[i][j]){
                printf(" ");
            }else if(g[i][j]==1){
                printf("-");
            }else if(g[i][j]==2){
                printf("/");
            }else{
                printf("\\");
            }
        }
        printf("\n");
    }
    return 0;
}
T3【吉利数(lucknum)】:
1、题目大意
有人认为一个数字中如果有4这个数字就是不吉利的。相对的,其他的数字就是吉利的。吉利的数字有1,2,3,5,6,7,8,9,10,..他想知道,第n个吉利的数字是多少?
2、比赛中的思考
我认为用枚举应该可以,但是无法拿全分,又没有别的思路,只能这样。
3、解题思路
我们可以发现n为9进制时,大于4的部分+1以9进制输出就是第n个吉利数。
4、AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll t,k;
int a[30],cnt;
int main(){
    scanf("%lld",&t);
    while(t--){
        scanf("%lld",&k);
        cnt=0;
        while(k){
            a[cnt++]=k%9;
            k/=9;
        }
        for(int i=cnt-1;i>=0;i--){
            if(a[i]>=4){
                printf("%d",a[i]+1);
            }else{
                printf("%d",a[i]);
            } 
        }
        printf("\n");
    }
    return 0;
}
T4【路灯照明(lighting)】:
1、题目大意
某一个格子的亮度为四盏路灯为他提供的亮度之和,例如 左上角的灯耗电量为 4, 右上角的灯耗电量为 7,右下角的灯耗电量为 8,左下角的灯耗电量为 0,那么 左上角这个格子的亮度就是4+2分之7+4分之7+0。现在我们对四个格子的最低亮度提出了要求,我们想要让四个格子的亮度都达到标准。你可以将每一盏灯的耗电量调节为任何一个大于等于零的整数,为了省电, 你希望四盏灯的耗电量之和尽可能的小,请问四盏灯的最小耗电量之和是多小?
2、比赛中的思考
一开使毫无头绪。到了快结束时才不得不用枚举来做。
3、解题思路
可以用二分查找来做,算出左下角格子的大致耗电量,然后用for循环在估计值的附近枚举即可,这样就不需要判断边界条件了。
4、AC代码
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int a, b, c, d;
bool check(int mid){
    for (int i = 0; i <= a; i++){
        for (int j = 0; j <= d; j++){
            int need = max(a - i - j / 4, d - j - i / 4); 
            if ((mid - i - j) / 2 < need){
                continue;
            }
            int now = mid - i - j;
            int bneed = max(0, b - i / 2 - j / 2);
            int cneed = max(0, c - i / 2 - j / 2);
            int bb = max(0, (bneed - now / 4) * 4 / 3);
            for (int k = max(0, bb - 5); k <= min(now, bb + 5); k++) 
                if (k + (now - k) / 4 >= bneed && k / 4 + now - k >= cneed){
                    return true;
                }
        }
    }
    return false;
}
int main(){
    CLOSE
    cin >> a >> b >> c >> d;
    int l = 0, r = a + b + c + d, ans = a + b + c + d;
    while (l <= r){
        int mid = (l + r) >> 1;
        if (check(mid)){
            ans = mid;
            r = mid - 1;
        }else{
            l = mid + 1;
        }
    }
    cout << ans << endl;
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值