做星期题还在用分支?NONONO,来试试循环吧~

起因:

在洛谷偶然刷到了这道题

 一看,嘶,边界条件有点多啊,先试试吧~

第一次的思路:

                                    先对总天数进行除以 7 的操作,得到星期数

                                    然后再对总天数进行对 7 取余的操作,得到剩余的天数

                                    星期数乘以 5 再加上剩余的天数就是实际游的天数

                                    最后加上特殊边界的判断:

                                    如果开始的时间是星期六,则将总天数减去两天

                                    如果开始的天数是星期天,则将总天数减去一天

                                    最后拿实际天数乘以 250 就是总里程了~

perfect!似乎思路没有问题,但是直觉告诉我并没有这么简单~

第一次的源码:

#include<iostream>
#include <algorithm>
using namespace std;

int main()
{
	int start, day;
	cin >> start >> day;
	int week = day / 7;
	int remain = day % 7;
	int real_day = week * (7-2) + remain;

	if (start == 6)
		real_day -= 2;
	else if (start == 7)
		real_day -= 1;
	
	int distance = real_day * 250;
	cout << distance << endl;

	return 0;
		

}

 第一次的结果:

emmmmmm,想了半天没想出来我的思路有什么问题,下个测试点看看~

这是测试点2的数据

 97061250 / 250 = 388,245,所以实际的天数应该是388245天

演算一下我代码的结果:

可以看到 real_day 的结果是没有错误的,但是因为开始的日期是星期天,所以结果少了一天的里程

思考了一下,难道说开始日期是星期六或者星期天也需要继续游吗?

于是我照着这个思路改了一下代码:

第二次的思路:                      

                        先对总天数进行除以 7 的操作,得到星期数

                        然后再对总天数进行对 7 取余的操作,得到剩余的天数

                        星期数乘以 5 再加上剩余的天数就是实际游的天数

                        与第一次不同的是不对特殊情况做判断

                        最后拿实际天数乘以 250 就是总里程了~

第二次的源码:

#include<iostream>
#include <algorithm>
using namespace std;

int main()
{
	int start, day;
	cin >> start >> day;
	int week = day / 7;
	int remain = day % 7;
	int real_day = week * (7-2) + remain;

	int distance = real_day * 250;
	cout << distance << endl;

	return 0;
		

}

第二次的结果:

可以看到这个思路并不是正确的,于是我又下了一个测试点~

这是测试点3的数据:

1750 / 250 = 7,10天不满两周,实际天数应该是8天,再减去开始游的当天,实际天数就是7天,也就是说如果开始天数是在星期六或者星期天的话,也是不需要游泳的(这条鱼还真是会偷懒...........)

这时候我突然灵光一闪(也可能是脑子一抽),如果week的天数刚好能被 7 整除,那么remain的天数就是 0,这时候无论是从哪天开始,都是经历了完整的 n 周,实际天数应该不会再受到星期六和星期天的影响,实际天数应为 n * (7-5)

于是我照着这个思路开始改代码

第三次的思路:

                                 先对总天数进行除以 7 的操作,得到星期数

                                 然后再对总天数进行对 7 取余的操作,得到剩余的天数

                                 星期数乘以 5 再加上剩余的天数

                                 如果remain为0,则表示经历了完整的n周,此时不进行特殊判断

                                 如果remain不为0,则表示经历了不完整的n周,此时加上边界判断

                                            加上特殊边界的判断(判断remain是否为0):

                                            如果开始的时间是星期六且remain不为0,则将总天数减去两天

                                            如果开始的天数是星期天且remain不为0,则将总天数减去一天

                                 最后拿实际天数乘以 250 就是总里程了~

第三次的源码:

#include<iostream>
#include <algorithm>
using namespace std;

int main()
{
	int start, day;
	cin >> start >> day;
	int week = day / 7;
	int remain = day % 7;
	int real_day = week * (7-2) + remain;

	if (remain != 0)
	{
		if (start == 6)
			real_day -= 2;
		else if (start == 7)
			real_day -= 1;
	}

	
	int distance = real_day * 250;
	cout << distance << endl;

	return 0;
		

}

第三次的结果:

纳尼? 还有什么条件我没判断到?

开始有点怀疑人生了 T^T

于是不信邪的我,下载了最后一个没过的测试点(当天下载测试点的机会用完了,这条测试点是我几天后才下的~)

这是八个测试点:

2204250 / 250 = 8817

演算一下我代码的结果:

也就是说多算了两天的路程~

嘶~

这时候看了看这个开始日期,emmmmm,星期四,还是我的幸运日,嘿嘿~

再看看余数,四天,也就是说停止游泳的日期是星期一,中间刚好有两天的休息日期,会不会就是这两天多算了?

这样想,如果开始的日期不是星期六或者星期天,不是整数周,但是最后一周的时候经过了星期六或者星期天这两天,那么也应该是要休息的,所以第三种方法的特殊情况判断是有问题的

第四次的思路:                          

                                    先对总天数进行除以 7 的操作,得到星期数

                                    然后再对总天数进行对 7 取余的操作,得到剩余的天数

                                    星期数乘以 5 再加上剩余的天数

                                    如果remain为0,则表示经历了完整的n周,此时不进行特殊判断

                                    如果remain不为0,则表示经历了不完整的n周,此时加上边界判断

                                            加上特殊边界的判断(判断remain是否为0):

                                            1.如果开始的星期数加上剩余的天数等于7或者开始的日期也是星期天

                                            则将实际天数减去1

                                          (比如说开始的天数是星期四,remain是3,那么 要经历星期四,星期

                                            五,星期六,休息一天,如果remain是4,那么要经历星期四,星期

                                            五,星期六,星期天,休息两天,此时跳转到第二种情况)

                                           

                                          (如果开始的日期是星期天,如果remain是1,则会当天休息一天,由

                                            于取余,所以余数不会超过6,所以其他情况下游泳时间最多持续到下

                                            周五,实际休息时间就是一天)

                                           (如果开始的日期是星期六,如果reamain超过了两天则会跳转到第二

                                             种情况,实际休息两天,如果只有一天,则当天休息实际休息一天 )

                                           (what's up,逻辑确实绕~,在复盘的时候差点把我cpu干爆了)

                                            2.如果开始的星期数加上剩余的天数大于8了,则表示经过了完整的一

                                            周,自然有两天的休息日,所以实际天数要减去2 

                                    最后拿实际天数乘以 250 就是总里程了~

第四次的源码:

#include<iostream>
#include <algorithm> 
using namespace std;

int main()
{
    int start, day;              
    cin >> start >> day;                     // 输入开始游泳的周数和经过的天数
    int week = day / 7;                      // 计算完整的周数
    int remain = day % 7;                    // 计算剩余的天数
    int real_day = week * (7-2) + remain;    // 计算实际游泳的天数

    
    if (remain != 0)                         // 如果remain不为0,需要考虑剩余天数对周数的影响
    {
        if (start + remain == 7 || start == 7 )
            real_day -= 1;                   // 如果剩余天数为0或1,则减少1天
        else if (start + remain >= 8)
            real_day -= 2;                   // 如果剩余天数大于等于2,则减少2天
    }

    long long distance = real_day * 250;     // 计算累计游泳的距离
    cout << distance << endl;                // 输出结果

    return 0;
}

第四次的结果:

此时我的大脑内不由唱起那首歌,喂 ~俺个炊饼~马飞诶~

太不容易了,这玩意设置为入门难度简直就是在骗人~

参考了一下其他大佬的解法,发现这玩意其实可以用循环来做(这不是分支结构的题吗????

用循环那可是方便太多了,根本不用考虑那么多边界条件,嘎嘎加上去就行了

用循环的思路:

                                主循环的次数用输入的天数 day 来控制,一共循环 day

                                循环体内用一个分支结构:

                                如果是星期六,则将星期数加一

                                如果是星期天,则将星期数重置为1

                                如果是其他日子,则将星期数加一,实际天数加一

用循环方法的源码1:

#include<iostream>              // 引入输入输出流头文件
#include <algorithm>            
using namespace std;            // 将std命名空间引入到作用域中

int main()                      // 主函数
{
    int start, day;       // 定义两个整数变量start和day,分别表示小鱼开始游泳的星期数和总天数
    cin >> start >> day;  // 从标准输入读取这两个整数
    int real_day = 0;     // 定义一个整数变量real_day,用于记录小鱼实际游泳的天数

    for (int i = 0; i < day; i++)       // 外层循环,表示小鱼游泳的总天数
    {
        if (start == 6 || start == 7)   // 如果小鱼开始游泳的那一天是星期六或星期日
        {
            if (start == 6)             // 如果小鱼开始游泳的那一天是星期六
                start++;                // 则将start加1,变成星期日
            else if (start == 7)        // 如果小鱼开始游泳的那一天是星期日
                start = 1;              // 则将start重置为1,表示小鱼从星期一开始游泳
        }
        else                            // 如果小鱼开始游泳的那一天不是星期六或星期日
        {
            start++;                    // 则将start加1,表示小鱼从下一天开始游泳
            real_day++;                 // 同时将real_day加1,表示小鱼实际游泳的天数增加一天
        }
    }

    // 计算小鱼实际游泳的距离,将real_day乘以每天游泳的距离250
    long long distance = real_day * 250;
    cout << distance << endl;                 // 将结果输出到标准输出流

    return 0;                                 // 函数返回0,表示正常退出
}

 注意在 if (week_day == 6 || week_day == 7) 中,这里不能只用一个if,如果start是6,执行后start会变成7,从而直接执行这句,这样每一轮都会多游泳一天

不起眼的一个小地方就可能会让我们困惑很久,我也是debug了以后才发现 T^T

参考了一下其他大佬的代码,这个思路的代码还可以更简洁一些~

用循环方法的源码2:

#include<iostream>                  // 引入输入输出流头文件
#include <algorithm>                // 引入算法头文件
using namespace std;                // 使用标准命名空间

int main()                          // 主函数
{
    int week_day, day;                  // 定义起始周和天数
    int real_day = 0;                   // 实际游泳的天数(不包括周末)
    cin >> week_day >> day;             // 输入起始天和天数

    for (int i = 0; i < day; i++)       // 遍历每一天
    {
        if (week_day != 6 && week_day != 7)     // 如果当前不是周末
            real_day++;                         // 累计游泳天数
        if (week_day == 7)                      // 如果当前是周日
            week_day = 1;                       // 更新起始周为周一
        else
            week_day++;                         // 更新起始天为下一天
    }

    long long distance = real_day * 250;        // 计算累计游泳距离
    cout << distance << endl;                   // 输出累计游泳距离

    return 0;                                   // 返回 0 表示程序正常结束
}

总结:

        正如伟大的维新派——理塘.顶真所言:都什么年代还在用传统分支

        我想了一下,其实可以说绝大多数能够用分支解决的,用循环也能解决

        比如判断一个数是不是偶数:

        用分支写就四条代码

#include <iostream>
using namespace  std;

int main() {
    int number;
    cin >> number;
    if ( number % 2 == 0 )
        cout << "True" << endl;
    else
        cout << "False" << endl;
    return 0;
}

那么如果用循环来写呢?

#include <iostream>
using namespace  std;

int main() {
    int number;
    cin >> number;
    int flag = 1;                        //用1表示这个数是偶数
    for(int i = 0; i < number; i++)
        flag = -flag;

    if(flag == 1)
        cout << "True" << endl;
    else
        cout << "False" << endl;
    return 0;
}

可以看到,虽然代码多了一些,但是也可以解决问题,循环也可以用来处理分支的问题,只是有些情况下,分支更好用罢了~

有些问题没必要在分支上死磕,万一用了循环有奇效呢~

----------------------------------------------------------分割线--------------------------------------------------------------

 

芜湖~终于写完了~

写这篇文章前前后后花了我快6小时左右,可以说的上是我目前为止写过最长的文章了,如果您觉得我这篇文章对您有帮助的话,那不妨点个赞和收藏呗,谢谢您~

如果您觉得我的文章有问题,请您私信我,我看到后就会及时改正,谢谢您!

感谢您的阅读!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值