Acwing4740. 跑圈

AcWing 4740. 跑圈 原题链接

1 暴力思路

首先声明,暴力的代码有一个样例是没有通过的

当L=1000000000 n=10000时, 报错 Segmentation Fault

求路过的大佬帮看看代码的错误在哪吧,跪谢

我的思路:总体思路是记录下每次经过机器时,此次跑步的方向,若是有两次方向相同且挨着,那么说明这次跑步是有效的,也就是被机器记录下来了

举例说明 :

若最后记录结果为 CCCAACACA

第二个和第一个方向相同且挨着,说明第二次跑步有效,有效次数加一

第三次和第二次方向相同且挨着,那么说明第三次跑步有效,有效次数加一

第五次和第四次挨着且方向相同,那么说明第五次跑步有效,有效次数加一

最后共计三次有效跑步

我个人认为思路是正确的,代码逻辑也没什么太大问题,不知道是因为数组越界还是因为哪里出问题了,导致报错Segmentation Fault

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
const int N = 10100;
long long int T;  //T组测试样例
long long int L,n; //跑道的长度L ,一共跑n段
long long int  d[N];   //每一段跑步的距离
char c[N];   //跑步的方向 //     a逆时针(选定正方向)   c顺时针 

char dir[N];    //记录每次跑过机器时的跑步方向

int main(){
    
    cin>>T;
   long long  int con=1;//记录这是第几组数据
 
    while(T--){   
        long long sum=0;//记录这是第几次过起跑线
        long long res=0;  // 有效跑圈次数
        cin>>L>>n;
        for(int i=0;i<n;i++)cin>>d[i]>>c[i];
       long long len = 0;;  //距离拍照机器的长度
       dir[0]=c[0];        //起点的起跑方向也应该被记录下来
        long long int j=1;  //作为记录每次经过起点的跑步方向数组的下标索引
        for(int i= 0;i<n;i++){
            
             long long len1=len;
            if(c[i]=='A'){  
             
                len-=d[i];
      //如果len运算完变号或等于0,说明又经过了一次起跑点,要添加一次方向
                if(len1>=0&&len<=0){dir[j++]=c[i]; 
                  sum++;
                    //   printf("dir[%d]== %c\n",j-1,dir[j-1]);
                    }
            }
            if(c[i]=='C'){
                
                len+=d[i];
                if(len1<=0&&len>=0){dir[j++]=c[i];
                  sum++;
                //  printf("dir[%d]== %c\n",j-1,dir[j-1]);
                }
            }
            while((len>0?len:-len)>=L){  //逆时针和顺时针都要取绝对值来判断
               dir[j++]=c[i];           //记经过起跑线时上一次的方向 
                //   printf("dir[%d]== %c\n",j-1,dir[j-1]);
                  sum++;
            //   printf("len1==%d  \n",len);
               if(len>0) len-=L;  
               if(len<0)len+=L;  
            // printf("len2==%d  \n",len);
            }
        //   printf("d[%d]==%d c== %c  ",i,d[i],c[i]);
        }
        
    //  cout<<"sum=="<<sum<<endl;
        for(int i=1;i<=sum;i++){
            //  cout<<dir[i]<<' ';
            if(dir[i]==dir[i-1])res++;  //两次方向相同就说明本次跑步被记录下来了
         
        }
        printf("Case #%lld: %lld\n",con,res-1);
        con++;
    }
    return 0;
}

2 y总正确思路

看完y总的思路,真的是妙啊。不得不说,这个思路是真的好

思路:将每次的跑步方向与上次的跑步方向进行对比,如果发生变化,将新的跑步方向作为正方向,上次的跑步方向视为反方向

每次更新后,都将新的跑步方向视为正方向

真的是妙极了 膜拜大佬

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>

using namespace std;
int T;//总共T组测试样例
int L,n;// 操场一圈长度为L 一共跑n段距离

int main(){
  cin>>T;
  int con=0;//统计这是第几次
   char op;  //记录跑步方向
  
  while(T--){
         con++;
         
         cin>>L>>n;
         
         long long len=0;//记录距离起跑点的距离
         long long res=0; //记录有效跑步次数
         
      for(int i=0;i<n;i++){
          int d;//这段跑步的距离
          char c;//跑步的方向
          
          cin>>d>>c;
          if(!i)op = c;  //第一次的起跑方向
          if(op ==c){   //若是这次起跑与上次跑步方向相同
               len += d; //加上最新跑的距离
               res += len/L;  //统计有效次数
               len = len%L;   //获得新的距离起点的长度
          }
          else {
              len-=d;
              if(len<0){
               op = c;  //如果len<0,说明一定越过了起跑线,更新一下方向
               len = abs(len); 
               res+=len/L;
               len = len%L;
          }
          }
      }
      printf("Case #%d: %lld\n",con,res);
  }
  return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海风许愿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值