【日期】车辆限行

【日期】车辆限行

2012年4月1日,北京是人民政府根据《中华人民共和国道路交通安全法》和《北京市实施〈中华人民共和国大气污染防 治法〉办法》有关规定,自2012年4月11日起,继续对机动车实施按车牌尾号工作日高峰时段 区域限行交通管理措施。
  根据规定,按车牌尾号限行的机动车车牌尾号分为五组,每13周轮换一次限行日,分别为:
(1) 自2012年4月9日至2012年7月7日:3和8、4和9、5和0、1和6、2和7
(2) 自2012年7月8日至2012年10月6日:2和7、3和8、4和9、5和0、1和6
(3) 自2012年10月7日至2013年1月5日:1和6、2和7、3和8、4和9、5和0
(4) 自2013年1月6日至2013年4月10日:5和0、1和6、2和7、3和8、4和9
(星期一到星期五)
现给出 2012 年 4 月 9 日之后的任意日期,如果不考虑国家统一的公假,只考虑日期一个因素,请计算指定日期要限行的车牌尾号。

(政府的公告确实有点意思,在时间衔接上和限号安排上公告(http://unn.people.com.cn/GB/14748/17574443.html)与公告(http://www.gov.cn/gzdt/2013-04/02/content_2367908.htm)之间有重叠,显然,后面的公告是覆盖前面的公告的,我们计算的时候,只能是“理论”上的事情,咱严格按照从 2012年4月9日 星期一 开始,每 13 周进行一次轮换计算就可以了。)

样例:

序号测试输入期待的输出额外进程
12012 7 9↵2 and 7.↵0
22012 7 12↵5 and 0.↵0
32012 7 14↵Free.↵0
42013 4 11↵2 and 7.↵0
52014 4 45 and 0.↵0

思路

首先观察规律(我用1表示 1 and 6,以此类推)

3 4 5 1 2
2 3 4 5 1
1 2 3 4 5
5 1 2 3 4
4 5 1 2 3
3 4 5 1 2
2 3 4 5 1
1 2 3 4 5
5 1 2 3 4
4 5 1 2 3
...

很明显每五轮循环一次,那每个循环内呢?以向右偏移为正方向

3 4 5 1 2 第0轮 offset = 0
2 3 4 5 1 第1轮 offset = 1
1 2 3 4 5 第2轮 offset = 2
5 1 2 3 4 第3轮 offset = 3
4 5 1 2 3 第4轮 offset = 4
3 4 5 1 2 第5轮 offset = 0
2 3 4 5 1 第6轮 offset = 1
1 2 3 4 5 第7轮 offset = 2
5 1 2 3 4 第8轮 offset = 3
4 5 1 2 3 第9轮 offset = 4
...

发现规律了吗?是的,偏移量刚好是周数模5!
那么我们就发现规律了:
只要先算出所求日期到2012-04-09的星期数,除以13(向下取整)得到轮换次数,再偏移对应偏移量即可(要注意周六周日的情况,以及偏移后大于5怎么办)

代码

#include <stdio.h>

int a[13] =  {0,31,28,31,30,31,30,31,31,30,31,30,31};
char x[6][9] = { "0","3 and 8.","4 and 9.", "5 and 0.", "1 and 6.", "2 and 7."};

int allday(int y, int m, int d)
{
	if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) a[2] = 29;
	int add = d;
	y--;
	for (int i = 1; i < m; i++) add += a[i];
	int day = y*365 + y / 4 - y / 100 + y / 400 + add;
	return day;
}

int main()
{
	int y, m, d,ad,day,wd;
	scanf("%d %d %d", &y, &m, &d);
	ad = allday(y, m, d);
	day = ad - 734602;
	wd = ad % 7;
	if (1 <= wd && wd <= 5)
	{
		wd -= day / 7 / 13;
		while (wd < 1) wd += 5;
		printf("%s\n", x[wd]);
	}
	else
		printf("Free.\n");
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值