ZOJ 3326 An Awful Problem (较清晰写法,附详细注解)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3326

题面:

An Awful Problem


Time Limit: 1 Second      Memory Limit: 32768 KB



In order to encourage Hiqivenfin to study math, his mother gave him a sweet candy when the day of the month was a prime number. Hiqivenfin was happy with that. But several days later,
his mother modified the rule so that he could get a candy only when the day of the month was a prime number and the month was also a prime number. He felt a bit upset because he could get fewer candies. What‘s worse, his mother changed the rule again and he
had to answer a question before he could get a candy in those days. The question was that how many candies he could get in the given time interval. Hiqivenfin wanted to cry and asked you for help. He promised to give you half of a candy if you could help him
to solve this problem.

Input

There are multiple test cases. The first line of input is an integer T (0 < T <= 50), indicating the number of test cases. Then T test cases follow. The i-th
line of the next T lines contains two dates, the day interval of the question. The format of the date is "yyyy mm dd". You can assume both dates are valid. Hiqivenfin was born at 1000-01-01 and would not die after 2999-12-31, so the queries are all
in this interval.

Hiqivenfin didn‘t seem to be an earthman, but the calendar was the same as that we usually use. That is to say, you need to identify leap years, where February has 29 days. In the Gregorian
calendar, leap years occur in years exactly divisible by four. So, 1993, 1994, and 1995 are not leap years, while 1992 and 1996 are leap years. Additionally, the years ending with 00 are leap years only if they are divisible by 400. So, 1700, 1800, 1900, 2100,
and 2200 are not leap years, while 1600, 2000, and 2400 are leap years.

Output

Output the number of candies Hiqivenfin could get in the time interval. Both sides of the interval are inclusive.

Sample Input

2
1000 01 01 1000 01 31
2000 02 01 2000 03 01

Sample Output

0
10

题意:

求两个日期间,月份是素数,天也是素数的日子有多少天。

解题:

比较烦的模拟题,但写多了也就有套路了。分年份相同和不同两种处理。相同则先分别处理两个零头月,然后模拟中间月份。不同则分别先处理两个零头年,然后模拟中间完整年份。其实年份之间可以每400年一个周期,找到第一个400年,然后直接计算,不过数据量比较小,没有必要这样处理。

代码:

#include<iostream>
using namespace std;
//是不是素数
bool prime[32]={0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1};
//每个月份多少天
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//判断是不是闰年
bool is_leapyear(int y)
{
	if((y%4==0&&y%100!=0)||y%400==0)return true;
	else return false;
}
int main()
{
    int t,y1,y2,m1,m2,d1,d2,cnt;
    cin>>t;
    while(t--)
    {
    	cnt=0;
    	cin>>y1>>m1>>d1>>y2>>m2>>d2;
    	//同一年
    	if(y1==y2)
    	{
    		//同一月份
	    	if(m1==m2)
	    	{
	    		if(prime[m1])
	    		{
				  for(int i=d1;i<=d2;i++)
	    		  {
		    		if(prime[i])
		    		cnt++;
	    		  }
	    		}
	    	}
	    	//不同月份
	    	else
	    	{
	    		//如果是闰年,不管2月是不是用到,直接改成29天,减少分支判断
	    		if(is_leapyear(y1))month[2]=29;
	    		//处理零头月份
	    		if(prime[m1])
	    		{
                   for(int i=d1;i<=month[m1];i++)
                   {
                   	 if(prime[i])cnt++;
                   }
		    	}
		    	if(prime[m2])
		    	{
	    			for(int i=1;i<=d2;i++)
	    			{
			    		if(prime[i])cnt++;
			    	}
	    		}
	    		for(int i=m1+1;i<=m2-1;i++)
	    		{
	    			//是素数月才判断
	    			if(prime[i])
	    			{
		    		  for(int j=1;j<=month[i];j++)
		    		  if(prime[j])cnt++;
	    			}
		    	}
		    	//记得将2月重新改回28天
		    	month[2]=28;
	    	}
	    }
	    //起始不同年份
	    else
	    {
	    	//2月特殊处理
    		if(is_leapyear(y1))month[2]=29;
    		//处理起始年
			//处理零头月
    		if(prime[m1])
    		{
		    	for(int i=d1;i<=month[m1];i++)
		    	if(prime[i])cnt++;
		    }
		    //处理其他月份
		    for(int i=m1+1;i<=12;i++)
		    {
		    	if(prime[i])
		    	{
    			  for(int j=1;j<=month[i];j++)
    			  {
			    	if(prime[j])cnt++;
			      }
		    	}
    		}
    		month[2]=28;
    		//处理终止年
    		//处理零头月
    		if(is_leapyear(y2))month[2]=29;
    		if(prime[m2])
    		{
		    	for(int i=1;i<=d2;i++)
		    	{
	    			if(prime[i])cnt++;
	    		}
		    }
		    //处理其他月份
		    for(int i=1;i<=m2-1;i++)
		    {
    			if(prime[i])
    			{
			    	for(int j=1;j<=month[i];j++)
			    	{
	    				if(prime[j])cnt++;
	    			}
			    }
    		}
    		month[2]=28;
    		//中间完整年份处理
    		for(int i=y1+1;i<=y2-1;i++)
    		{
    			//闰年53天,平年52天
		    	if(is_leapyear(i))
		    	cnt+=53;
		    	else cnt+=52;
		    }
    	}
    	cout<<cnt<<endl;
    }
	return 0;
}
时间: 2024-10-23 08:31:06

ZOJ 3326 An Awful Problem (较清晰写法,附详细注解)的相关文章

ZOJ 3326 An Awful Problem 模拟

只有在 Month 和 Day 都为素数的时候才能得到糖 那就模拟一遍时间即可. //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <fstream> #include <cstring> #include <cmath> #include <sta

zoj3326An Awful Problem

题目链接: 点我点我 题目: An Awful Problem Time Limit: 1 Second      Memory Limit: 32768 KB In order to encourage Hiqivenfin to study math, his mother gave him a sweet candy when the day of the month was a prime number. Hiqivenfin was happy with that. But sever

ZOJ 4009 And Another Data Structure Problem(ZOJ Monthly, March 2018 Problem F,发现循环节 + 线段树)

题目链接  ZOJ Monthly, March 2018 Problem F 题意很明确 这个模数很奇妙,在$[0, mod)$的所有数满足任意一个数立方$48$次对$mod$取模之后会回到本身. 所以开$48$棵线段树,和一个永久标记.当对某个区间操作时对这个区间加一层永久标记. 即当前我要查找的第$x$层,实际找的是第$up[i] + x$层. 时间复杂度$O(48nlogn)$ #include <bits/stdc++.h> using namespace std; #define

伪静态规则写法RewriteRule-htaccess详细语法使用

一.正则表达式教程 伪静态规则写法RewriteRule-htaccess详细语法使用教程分享 简单说下:伪静态实际上是利用PHP把当前地址解析成另外一种方法进行访问网站!要学伪静态规则的写法,你必须得懂一点正则,不会没关系,照着下面的套就行 一.正则表达式教程 有一个经典的教程: 正则表达式30分钟入门教程这个教程的确很简单,看完基本上写一些简单的正则就没有问题了.正则是一个需要长期使用的工具,隔段时间不用会忘记,所以我每次都看一遍这个教程.其实学过之后重要的就是一点内容. 简单罗列如下: .

ZOJ 1457 Prime Ring Problem(dfs+剪枝)

?? Prime Ring Problem Time Limit: 10 Seconds      Memory Limit: 32768 KB A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime

zoj 2778 - Triangular N-Queens Problem

题目:在三角形的棋盘上放n皇后问题. 分析:找规律题目,按照题目的输出,可以看出构造法则: 先填奇数,后填偶数.下面我们只要证明这种构造的存在性即可. 解法:先给出集体构造方法,从(1,n-f(n)+1) 开始填充奇数点: 填充所有的(1+2k,n-f(n)+1+k){其中f(n)就是最大填充数,1+2k<=n-f(n)+1+k} : 之后开始从(2,n-f(n)+1+k+1)开始填充偶数点,由于奇数点只能攻击奇数点: 偶数点只能攻击偶数点,所以只要保证每行一个皇后就可以了. 证明:我们只需要证

【转】作用域、链接属性、存储类型总结--转载学习,很清晰,很详细

标识符: 首先,在讨论这三种东西之前,详细说明一下C语言中的标识符. 标识符是用户编程为变量.常量.函数.语句等指定的名字,就好比人名一样的东西. 标识符的命名规则如下: 1.只能由字母.数字.下划线组成,并且首字符不能是数字: 2.不能把C语言的关键字作为标识符: 3.对大小写敏感: 其次,需要明确,作用域和链接属性是在标识符范畴内讨论的,存储类型是在标识符中的变量范畴内讨论的. 作用域: 标识符的作用域就是程序中该标识符可以被使用的区域,由它的声明位置决定. 分为以下四类: 1.文件作用域

CSS3常用功能的写法

随着浏览器的升级,CSS3已经可以投入实际应用了. 但是,不同的浏览器有不同的CSS3实现,兼容性是一个大问题.上周的YDN介绍了CSS3 Please网站,该网站总结了一些常用功能的写法. 以下就是这些写法的详细介绍.所有代码都经过了Firefox 3.6和IE 8.0的验证,原文的错误之处也已得到改正. 一.圆角(Rounded Corner) .box_round { -moz-border-radius: 30px; /* FF1+ */ -webkit-border-radius: 3

.gitignore 规则写法 - 在已忽略文件夹中不忽略指定文件、文件夹【注意项】

1. 在已忽略文件夹中不忽略指定文件夹 /node_modules/* !/node_modules/layer/ 2. 在已忽略文件夹中不忽略指定文件 /node_modules/* !/node_modules/layer/layer.js [注意项]注意写法 要忽略的文件夹一定要结尾 /* ,否则不忽略规则将无法生效 3. 其他规则写法 (附) 以斜杠"/"开头表示目录: 以星号"*"通配多个字符: 以问号"?"通配单个字符 以方括号&qu