1098: 素MM
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 26 Solved: 15
[Submit][Status][Web Board]
Description
素数有很多神奇的性质,所以很美。我们知道一个日期将年、月、日按顺序连接在一起可以组成一个八位数,例如2011年3月6日可以写成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 ); } } }