CSP_记录一些小坑

小明种苹果续
几分钟码完的代码交上去50分百思不得其解,终于还是搜了一下博客才知道有很多“英雄所见略同”的博客qwq
D统计的是发生落果的树的数目,写程序时一旦发生落果就D++,同一棵树可能多次落果,但是这样写D会统计多了,最后改成根据drop数组重新统计了D
这个教训就是,虽然把一些操作放在同一个循环中进行能提高效率,但是也很容易出一些隐蔽的错误,因此在时间复杂度要求不是很严格的情况下还是分开几个循环写不容易出错。
在这里插入图片描述
·
·
·
·
·
小明放学
分析出应该用longlong存储才行了,但是define的时候把 #define int long long 错写成#define long long int了,导致一度60分。当然最好以后都直接longlong开。

#include <iostream>
using namespace std;
#define int long long
signed main() {
    int r,y,g;
    cin >> r >> y >> g;
    int n;
    cin >> n;
    //灯变化红 绿 黄
    //数字   1 3 2
    int res=0;
    for(int i=0;i<n;i++){
        int k,t;
        cin >> k >> t;
        if(k==0){
            res+=t;
        }else if(k==1){//红灯
            int pass=res%(r+y+g);
            if(pass<t) res+=(t-pass);
            else if(pass>=t && pass<t+g)//原来pass<=t+g,改不改都对,因此题目应该没考察这么特殊的边缘情况,但是严格来讲不该取等
                res+=0;
            else res+=(r+y+g+t-pass);
        }else if(k==2){
            //遇到黄灯
            int pass = res%(r+y+g);
            if(pass<t+r)//剩余黄灯+红灯
                res+=(t+r-pass);
            else if(pass>=t+r && pass <t+r+g)//<=改成<
                res+=0;
            else res+=(y+r)-(pass-(t+r+g));
        }else if(k==3){
            //遇到绿灯
            int pass = res%(r+y+g);
            if(pass<t)//剩余ts 把等号移到后面
                res+=0;
            else if(pass>=t && pass <=t+y+r)
                res+=t+y+r-pass;
        }
    }
    cout << res;
    return 0;
}

·
·
·
·
·
·
买菜
对于区间[1,5],设置1234为true这种,即1为true表示1-2可以闲聊,这样比较两者true重合的个数就好,此思路更简单。(main函数)
如果区间 [1,5],设置12345都为true,统计的时候需要减1,同时如果发生 [1,5], [6,7],那么1-7都为true了,但是5到6是不能算进去的,需要特殊处理更为麻烦,也能做出来。(main1函数)

#include <iostream>
using namespace std;
bool H[1000001]={false};
//main1处理的是都是开区间 所以还要涉及-1的问题 假如说处理为前闭后开区间,即[1,2]只是1为true ,1为true表示12
int main(){
    int n;
    cin >> n;
    for(int i=1;i<=n;i++){
        int a,b;
        cin >> a >> b;
        for(int f=a;f<b;f++)
            H[f]=true;
    }
    int res=0;
    for(int i=1;i<=n;i++){
        int c,d;
        cin >> c >> d;
        for(int j=c;j<d;j++){
            if(H[j]) res++;
        }
    }
    cout << res;
}
int main1() {
    int n;
    cin >> n;
    for(int i=1;i<=n;i++){
        int a,b;
        cin >> a >> b;
        for(int f=a;f<=b;f++)
            H[f]=a;
    }
    int res=0;
    for(int i=1;i<=n;i++){
        int c,d;
        cin >> c >> d;
        int tmp=0;
        int flag=-1;
        for(int j=c;j<=d;j++){
            if(H[j]>0){
                if(flag==-1){
                    tmp++;
                    flag=H[j];
                }else if(H[j]==flag){
                    tmp++;
                }else{
                    res+=tmp-1;
                    tmp=1;
                    flag=H[j];
                }
            }else{
                if(tmp>0){
                    res+=tmp-1;
                    tmp=0;
                    flag=-1;
                }
            }
        }
        if(tmp>0){
            res+=tmp-1;
        }
    }
    cout << res;
    return 0;
}

火车购票:此题没坑,就是想记录一下代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
bool seats[101]= {false};
int main()
{
    int n;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        int t;
        cin >> t;
        bool flag=false;
        for(int row=1; row<=96; row+=5)
        {
            for(int col=row; col<=row+5-t; col++)
            {
                bool f=true;
                for(int k=col; k<col+t; k++){
                    if(seats[k]==true){
                        f=false;
                        break;
                    }
                }
                if(f==true){
                    flag=true;
                    for(int p=col;p<col+t;p++){
                        seats[p]=true;
                        cout << p << " ";
                    }
                    break;
                }
            }
            if(flag==true) break;
        }
        if(!flag){
            for(int i=1;i<=100;i++){
                if(seats[i]==false){
                    seats[i]=true;
                    cout << i << " ";
                }
            }
        }
        cout << endl;

    }
    return 0;
}

公共钥匙盒
其实这个题也不难,对借阅时间和归还时间排序依次处理即可,一开始只得了30分,仔细审题发现题目要求同时归还时按照钥匙编号小的归还,cmp的时候只注意让同一时刻归还在先了,所以遇到这种情况,一般都是审题出的问题,耐心读一遍题,考虑一下是不是漏了什么条件~

Z字形扫描
耐心debug就会一点点发现问题在哪的~

#include <iostream>

using namespace std;
int arr[501][501];
int dx[2]= {1,-1};
int dy[2]= {-1,1};
bool isLegal(int x,int y,int n)
{
    if(x>=1 && x<=2*n-1 && y>=1 && y<=2*n-1)//2*n-1 X 2*n-1范围内都是合法的,但只有n*n范围内才会输出
        return true;
    else
        return false;
}
bool isCnt(int x,int y,int n){
    if(x>=1 && x<=n && y>=1 && y<=n)
        return true;
    else return false;
}
int main()
{
    int n;
    cin >> n;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            cin >> arr[i][j];
        }
    }
    for(int i=1; i<=2*n-1; i++)//为了能扫描到(n,n)位置,需要右上角/左上角的位置到2*n-1
    {
        int x,y;
        if(i&1)
        {
            //奇数从(i,1)开始向右上方扫描
            x=i;
            y=1;
        }
        else
        {
            //偶数从(1,i)开始向左下方扫描
            x=1;
            y=i;
        }
        while(isLegal(x,y,n))
        {
            if(isCnt(x,y,n))
            {
                cout << arr[x][y] << " ";
            }
            x+=dx[i&1];
            y+=dy[i&1];
        }
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值