HUT1098 素MM

  

1098: 素MM

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 26  Solved: 15
[Submit][Status][Web Board]

Description

素数有很多神奇的性质,所以很美。我们知道一个日期将年、月、日按顺序连接在一起可以组成一个八位数,例如201136日可以写成20110306。我的某个MM的生日组成的数是一个素数。偶尔我叫她素MM,没人知道是啥意思,她自己也不知道。O(∩_∩)O哈哈~我心里可是真的美美的(⊙o⊙)哦!

嗯,什么?你的生日也是素数?你也想做“素MM”或者“素GG”?那好吧,不过我可是很小气的哦!只有你出生在1988年或者1989年我才让你做“素MM”或“素GG”。要不然,你把这两年里日期组成的数是素数的找出来也可以——没准还带你到浙大去“旅游”呢!

Input

  无

Output

  1988年与1989年,这两年里的日期所组成的素数。每个素数占一行。

Sample Input 

Sample Output

19880101
19880111
19880117
19880129
19880221
……

HINT

“……”代表后面还有素数没有输出。你输出时也要将后面的素数输出。

  自己学校上的一道题目,题目很有意思,一下子就吸引了我们的注意力,看了题目后马上会想到自己的生日号码是不是一个素数呢,可惜哥是24号生的。。要是用筛选法的话,马上就被KO了,呵呵。

  回到题目上来,这里要求例出 19880101 到 19891231 之间满足年月日分布的所有素数,当然这里还是用筛选法来解决这个问题,做一个特殊处理,把那个要判的数字都减去一个 19800000 这样就只需要开一个10000的数组就可以了( 其实减去19880000就可以了,数组就可以还小一点了 ),然后再利用 2 - sqrt(19891231) 之间的素数来筛出我们所要求的素数。

  代码如下:

#include <stdio.h>
#include <math.h>

char hash[100000], num[10000];

const int lim= sqrt( 19891250 );

int monday[13]= { 0, 1, -1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 };

bool legal( int x )
{
	int temp= x% 10000;
	int mon= temp/ 100, day= temp% 100;
	if( mon>=1&& mon<= 12 )
	{
		if( mon!= 2 )
		{
			if( day<= 30+ monday[mon] )
			{
				return true;
			}
			return false;
		}
		else
		{
			if( x< 19890000 )
			{
				if( day<= 30+ monday[mon]- 1 )
				{
					return true;
				}
				return false;
			}
			else
			{
				if( day<= monday[mon] )
				{
					return true;
				}
				return false;
			}
		}
	}
	return false;
}

int main(  )
{
	for( int i= 2; i<= lim; ++i )
	{
		if( !num[i] )
		{
			for( int j= i+ i; j<= 1412; j+= i )
			{
				num[j]= 1;
			}
			for( int j= i+ i; j<= 19891231; j+= i )
			{
				if( j- 19880000> 0 )
				{
					hash[ j- 19800000 ]= 1;
				}
			}
		}
	}
	for( int i= 80101; i<= 100000; ++i )
	{
		if( !hash[i]&& legal( i ) )
		{
			printf( "%d\n", 19800000+ i );
		}
	}
}
原文地址:https://www.cnblogs.com/Lyush/p/2112055.html