所谓筛选法就是从全集中将不合格的项全部删去,剩下的就是答案。- k1 f4 Z4 \( I% T! n
" R0 `) {" B( ~" J: ?: c5 t
1: 求1-100之间的质数7 s; _/ E$ k: y3 O3 y
! J1 z g$ P g% _: X6 F h
原理:先将2的倍数全部划掉,再将3的倍数全部划掉……直到将10的倍数全部划掉(10^2 = 100 )。剩下的就是质数.0 _: D4 n# X8 r( f e( a8 f
6 ^2 r( R- T; w& |1 T" ^void fun1() b% [! b5 g% F$ ~0 [. u/ m; m4 n{ , n/ A: Q ?$ n0 Z0 E) x6 H0 [/ H int i, j; & x* w9 F5 w4 f0 `2 ~ bool flag[100];5 ^) ?7 J p$ y5 F; V, W
" T+ V, e' o$ o x# N% w. N
for ( i = 2; i < 100; i++ ) / Z" Z. P7 W* p" Q flag = true;; w+ T) p: N% m- G8 t& G
& g/ h9 W+ [, @# {# O2 u //下面开始划掉合数 + M _' |/ @+ }# T7 `5 W9 S for ( i = 2; i < 10; i++ ) //因为合数的最小正因数不大于它的平方根7 {" C* k( H5 k [: E4 I$ m
{ 1 y: r3 W0 J2 ^/ l, B if ( flag == false ) ( Q* `; ~% } M& F continue; //既然i已经是合数,它的倍数应该已经被划掉 4 ?1 N; l( l0 S, l for ( j = 2; j * i < 100; j++ )//划掉i*j ) v5 C# Z: p# i0 n flag[i*j] = false;" I" P$ @2 B7 M, V7 C
} % \7 w# @) h5 S% V0 ~1 N* N2 }+ {) k* G+ D* l' H8 J
//输出结果9 W8 c$ x( f0 U8 H
for ( i = 2; i < 100; i++ ) " U0 i( P# L2 t- c% a8 {% w+ f if ( flag ) 7 C. y* h( i; { g3 m/ _ cout << i << ' '; + P1 ~( [8 c4 O- J9 T} 2 \) ]) M6 w/ O, @3 J ( \; u' N" y" j" r+ h2: 30个人站成一圈,从第一个人开始报数,凡报到5的拉出去毙了,剩下的人接着从1开始报,直到只剩一人放掉。想活命该站哪? 9 u# T4 j4 [* }* Z v( N4 Y: f2 k% B( Q# T4 v8 f: x
这是个经典问题,解法就是模拟整个过程,有点类似于循环队列。' s+ F: n$ F8 y9 l( W% j; b# N
* @+ i( V. y% A+ {& V' ?$ K, N 另外,为了程序上处理方便,可以假定所有的人都拉去毙了,然后看一下最后一个被毙掉的是谁。另一处为了处理方便而采取的措施是pos的初始值设为-1.很多时候,对问题的问法稍作变动,或者将初始值、加减变量的位置稍作调整,用程序处理起来会方便很多。" `0 y& z1 s* ]/ R2 M/ b" t
* u* S0 {2 T! t" J
void fun2()0 F* D' Z) O" C ~7 K0 i+ X
{ + N3 o0 P; I4 S# E bool flag[30];//标记第i个人的状态,false已被毙掉,true还没被毙掉 0 i2 l5 M9 l2 C. Y |( E5 u8 D% V- H0 I9 z; J' ~. V% @
for ( int i=0; i< 30; i++ ) T- U# L& |2 L- P, n8 |" c flag = true;' i$ f- c4 h: Q$ W r
3 ~! t* B0 E# [4 X
int n = 30;//还剩几个人; }, R$ C& i z" y* g" M
int cnt;+ K0 v: [6 l& P! q# @1 Q
int pos = -1;//初始值不一定从0开始,设为-1处理起来较方便 - K2 _9 h9 n4 b9 m+ D while ( n > 0 ) % D+ V1 v& q) g { 6 r4 K6 d6 B; } cnt = 0; : r6 y U% C# j0 R0 }( i while ( cnt < 5 )5 ]+ s0 p4 t9 E! f1 { |2 n
{& t6 d2 y" x" C
if ( ++pos == 30 ) - Z3 B- k3 n, F" f' B2 t+ J* Z' | pos = 0; 3 n( Q. Y; O+ E if ( flag[pos] )//此人还没被毙掉 9 R; b+ |3 z1 \7 c7 h cnt ++;& f0 |8 g- W9 f
} ' l0 q ^6 l* U# I0 y8 P5 f- ?9 o //退出时cnt == 5,pos指向报5的人, J. q5 F6 ]3 g, C
flag[pos] = false;//毙掉' ?; ^. A3 C% O, N6 f7 [& q
n --;//剩余人数减1 ' d9 ]3 q" P" e' E. Q9 l8 k } / g, f% c1 S, P6 C. x //最后一个被毙的就是幸存者 / r6 g4 K: s) o( {. z& O //之所以加1是因为程序中从0开始计数,输出却以1开始计数 5 e. c% ]# o' d2 ~- ?3 N cout << pos + 1 << ' '; $ ^5 U. v" j# e' i" z9 s* L8 e}$ m2 f& A# m; c
" V" y/ j4 Q3 Q" [' Y3: 一个数被5除余3,被7除余2,求此数最小为几。 ) i* n. m- a2 H; S, A 3 z: n' D# G5 [# ?) A 筛选法不一定非要标记true/false,有时候也可以使用计数来进行筛选,这个问题就是一例。6 k* i/ u4 }; Q$ Z
首先,如果问题有解,则解必小于 5 * 7 = 35,只用在此范围内筛选即可。8 {$ ^7 q! `% g: x
在程序处理上,如果一个数满足一个条件,就将计数值加1,最后计数值为3的即为所求。 6 T, [! U' q- v$ Z) J# F7 w3 W* y$ N, T; t( _5 a. G7 ^4 d
void fun3()' t" m, O2 {; ]9 h# j' Q
{* X! q O1 j& r; S4 V- t ^
int a[105];//105 = 5 * 7. e" C, ]( L' g! y o U
int i;/ ?3 \$ U0 R7 h9 Q! N
//计数清0: S. M+ i' C# |1 p& f( B
for ( i = 0; i < 35; i++ ) . G; n9 Y) h' v a = 0; 2 X: O) g& f: y% B; l //开始筛选 / [3 w. l* E8 [3 B& S9 ^ for ( i = 3; i < 35; i += 5 ) & v B& J+ [) f" P- R a ++;, I, C) F h% d$ C1 l
for ( i = 2; i < 35; i += 7 ); |7 X6 a: Z. t. [3 X# ~. F& d
a ++;- G) H8 s& }/ e% j$ [
. s" _0 I& ?: ]4 r( ^+ Y
for ( i = 0; i < 35; i++ ); j% J9 p) K: G/ Z0 A
if ( a == 3 )! B3 k% w2 g% ^$ A+ s0 z
{7 u L g- C$ j
cout << i << endl; / j6 _1 \, a, A5 w; A return;: |& U5 e' Q1 U& `" P; p1 U
} ) G5 G. W0 N$ u5 c V5 V //如果执行到这里说明无解 & B( e$ p1 R: Z+ Q" o! l cout << "No Answer!" << endl; + N+ ]# M6 a, j9 w' K}" n2 i/ ?, O4 I