有周期且避开周末的经典例题

原题:

输入输出格式
输入格式:

输入两个整数x,n(表示从周x算起,经过n天,n在long int范围内)。
输出格式:

输出一个整数,表示小鱼累计游泳了多少公里。
输入输出样例


输入样例#1:

3 10


输出样例#1:

2000

方法一:分情况找规律,主要有以下几种情况
①x<6&&x+n<=6 => 250*n
用程序实现:

if(x<6&&x+n<=6) printf("%d",250*n);

②x<6 && x+n7 => 250*(n-1)
x<6 && x+n
8 => 250*(n-2)
~
x<6 && x+n14 => 250*(n-3)
x<6 && x+n
15 => 250*(n-4)

可以看出这个部分的规律可以用循环实现

for(i=1;1;i++)
{
   if(x<6&&(x+n)==7*i)
{
 printf("%d",250*(n-(2*i-1)));
 break;
}
   else if(x<6&&(x+n)==(7*i+1))
   {
    printf("%d",250*(n-2*i));
    break;
   }
   else break;
   }

③x<6 && 8<x+n<=13 => 250*(n-2)
~
x<6 && 15<x+n<=20 => 250*(n-4)
~
x<6 && 22<x+n<=27 => 250*(n-6)

还是可以明显看出这段规律可以用循环写出:

 for(i=1;1;i++)
  {
   printf("%d\n",i);
   if(x<6&&(x+n)>(7*i+1)&&(x+n)<=(7*i+6))
   {
    printf("%d",250*(n-2*i));
    break;
}
else break;
}

④x==6 && x+n<=8 => 0

if(x==6&&(x+n)<=8) printf("0");

⑤x6 && 8<x+n<=13 =>250*(n-2)
~
x
6 && 15<x+n<=20 =>250*(n-2)
~
x==6 && 22<x+n<=27 =>250*(n-2)

可以看出这里可以直接归纳入上一段程序,即将x<6改为x<=6即可

for(i=1;1;i++)
  {
   printf("%d\n",i);
   if(x<=6&&(x+n)>(7*i+1)&&(x+n)<=(7*i+6))
   {
    printf("%d",250*(n-2*i));
    break;
}
else break;
}

但分析问题时最好将这两种情况分开分析,否则易混淆
⑥x6 && x+n14 =>250*(n-3)
~
x6 && x+n21 =>250*(n-5)
~
x6 && x+n28 =>250*(n-7)

程序如下:

 for(i=2;1;i++)
{
 if(x==6&&(x+n)==7*i)
 {
  printf("%d",250*(n-(2*i-1)));
  break;
 }
 else break;
}

⑦x==7 && x+n<=8 =>0

 if(x==7&&x+n<=8) printf("0");

⑧x7 && 8<x+n<=13 =>250*(n-1)
~
x
7 && 15<x+n<=20 =>250*(n-3)
~
x==7 && 22<x+n<=27 =>250*(n-5)

这一段用程序实现如下:

 for(i=1;1;i++)
{
 if(x==7&&(x+n)>(7*i+1)&&(x+n)<=7*i+6)
 {
  printf("%d",250*(n-i));
  break;
 }
 else break;
}

⑨x7 && x+n14 =>250*(n-2)
~
x7 && x+n21 =>250*(n-4)
~
x7 && x+n28 =>250*(n-6)

程序如下:

for(i=2;1;i++)
{
 if(x==7&&(x+n)==7*i) 
 {
     printf("%d",250*(n-i));
     break;
 }
 else break;
}

⑩x7 && (x+n)15 =>250*(n-3)
~
x
7 && (x+n)22 =>250*(n-5)
~
x
7 && x+n
29 =>250*(n-7)

程序:

for(i=2;1;i++)
{
         if(x==7&&(x+n)==(7*i+1))
         {
          printf("%d",250*(n-(i+1)));
          break;
   }
   else break;

对于这种方法有以下几点说明:
(1)每一段一个for只是为了说明问题,如果直接把它们按顺序放在一起构成整个程序是会出错的,比如第一个假设i=0时,x,n不满足两个条件,就会直接跳出循环。而原意是希望用循环找出满足条件的,如果循环完了,都没有满足的才跳出这一个循环,进入下面的判断。
但如果去掉最后的break;又会使得程序在遇到x,n不满足两个条件时,无限循环,跳不出循环。
(2)对于x与n的含义要正确理解,例如
x<6 && 8<x+n<=13 => 250*(n-2)
x<6表示开始游泳时间为周一~周五中任意一天;n表示的是从这一天开始经过了n天,值得注意的是包括了周x当天自身;对于x+n的理解:例x=1,n=7则x+n=8,表示从周一开始算,过了7天所以x+n表示把本周周天刚好过完;所以8<x+n<=13表示结束的那一天在下周一到下周五之间,此时只过了上一个双休日,所以它游了n-2天,也就游了250*(n-2)公里。
(3)需要考虑x<6,x=6,x=7三种大的情况,而每一种又要考虑x+n(结束的那一天在周一~周五,周六,周天并把当天过完)三种情况。
(4)正确代码如下,其中将原来每个for中的else break;语句删去,并放入了一个for循环,就能实现一段满足不了可以进行后续的判断的功能,并且能实现没有x,n与当下的i配对时i+1再从头开始判断的循环功能。所以对于之前有的i从2开始循环有的从1开始循环的问题不需担心,对于输入的确定的x,n一定输出的只有一个解,也就只有那一段程序能实现,不会在不对应的程序段因为i的不同而满足并输出。所以放心的把各个程序段放进一个for中。

/*正确代码*/ 
#include<stdio.h>
int main()
{
 int x,n;
 int i;
 scanf("%d%d",&x,&n);
 if(x<6&&x+n<=6) printf("%d",250*n);
 for(i=1;1;i++)
 {
    if(x<6&&(x+n)==7*i)
    {
  printf("%d",250*(n-(2*i-1)));
  break;
    }
     if(x<=6&&(x+n)>(7*i+1)&&(x+n)<=(7*i+6))
     {
      printf("%d",250*(n-2*i));
      break;
  }
  if(x==6&&(x+n)==7*i)
  {
   printf("%d",250*(n-(2*i-1)));
   break;
  }
  if(x==7&&(x+n)>(7*i+1)&&(x+n)<=7*i+6)
  {
   printf("%d",250*(n-(2*i-1)));
   break;
  }
  if(x==7&&(x+n)==(7*i+1))
          {
           printf("%d",250*(n-(2*i-1)));
           break;
    } 
  if(x==7&&(x+n)==7*i) 
  {
      printf("%d",250*(n-(2*i-2)));
      break;
  }
  if(x==6&&(x+n)<=8)
  {
      printf("0"); break;
  }
  if(x==7&&x+n<=8)
  {
      printf("0");
      break;
  }
     else if(x<6&&(x+n)==(7*i+1))
    {
         printf("%d",250*(n-2*i));
         break;
    }
   
    };
   
}

方法二:简单易懂的程序:

#include<stdio.h>
main()
{
 int x,n,i,s=0;
 scanf("%d%d",&x,&k);
 for(i=1;i<=k;i++)
 {
  if(x!=6&&x!=7)
  {
   s+=250;
  }
  else if(x==6)
  {
   x=7;
  }
  else if(x==7)
  {
   x=1;
  }
 }
 printf("%d",s);
 } 

理解:非周末直接计数,周末直接跳过,用for直接实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值