2010.11.9南高模拟赛
NOIP模拟测试题
第1题速算游戏
源程序名 fun.pas|c|cpp
输入文件名 fun.in
输出文件名 fun.out
时间限制 1s/testcase
空间限制 32MB
问题描述
jyx和cyy打赌,比谁24点算得快,算得慢的那个人请客。24点的规则是这样的:给定4个1..9的整数,用括号改变运算顺序,通过加、减、乘、除通的一系列运算,得到整数24,注意所有中间结果必须是整数(例如(2*2)/4是允许的,而2*(2/4)是不允许的)。为了赢得这个比赛,请写一个程序帮助我作弊,快速地计算出24点。
输入数据
一行4个整数,为给定的4个数字。输入数据保证有解。
输出数据
一行,以字符串的形式输出结果,注意将每一步的运算的括号补齐(例如(3+5)+6和3*(5+6))如果有多种解答,输出字典顺序最小的一个。
样例输入
2 3 5 7
样例输出
(((3*5)+2)+7)
第2题素数密度
源程序名 prime.pas|c|cpp
输入文件名 prime.in
输出文件名 prime.out
时间限制 1s/testcase
空间限制 32MB
问题描述
给定区间[L, R](L <= R <= 2147483647,R-L <= 1000000),请计算区间中素数的个数。
输入数据
两个数L和R。
输出数据
一行,区间中素数的个数。
样例输入
2 11
样例输出
5
第3题数页码
源程序名 count.pas|c|cpp
输入文件名 count.in
输出文件名 count.out
时间限制 1s/testcase
空间限制 32MB
问题描述
一本书的页码是从1-n编号的连续整数:1, 2, 3, ... , n。请你求出全部页码中所有单个数字的和,例如第123页,它的和就是1+2+3=6。
输入数据
一行为n(1 <= n <= 10^9)。
输出数据
一行,代表所有单个数字的和。
样例输入
3456789
样例输出
96342015
第4题单人纸牌
源程序名 double.pas|c|cpp
输入文件名 double.in
输出文件名 double.out
时间限制 1s/testcase
空间限制 32MB
问题描述
单人纸牌游戏,共36张牌分成9叠,每叠4张牌面向上。每次,游戏者可以从某两个不同的牌堆最顶上取出两张牌面相同的牌(如黑桃10和梅花10)并且一起拿走。如果最后所有纸牌都被取走,则游戏者就赢了,否则游戏者就输了。
George很热衷于玩这个游戏,但是一旦有时有多种选择的方法,George就不知道取哪一种好了,George会从中随机地选择一种走,例如:顶上的9张牌为KS, KH, KD, 9H, 8S, 8D, 7C, 7D,6H,显然有5种取法:(KS, KH), (KS, KD), (KH, KD), (8S, 8D), (7C, 7D),当然George取到每一种取法的概率都是1/5。
有一次,George的朋友Andrew告诉他,这样做是很愚蠢的,不过George不相信,他认为如此玩最后成功的概率是非常大的。请写一个程序帮助George证明他的结论:计算按照他的策略,最后胜利的概率。
输入数据
9行每行4组用空格分开的字串,每个字串两个字符,分别表示牌面和花色,按照从堆底到堆顶的顺序给出。
输出数据
一行,最后胜利的概率,精确到小数点后6位。
样例输入
AS 9S 6C KS
JC QH AC KH
7S QD JD KD
QS TS JS 9H
6D TD AD 8S
QC TH KC 8D
8C 9D TC 7C
9C 7H JH 7D
8H 6S AH 6H
样例输出
0.589314
一题输出叙述有点问题,既然水题还想整人,弃之!
二题如果没做过这样的题,还真会被难住唉...
后来问大牛们说可以用中国猜想:
假设x是质数,且(a,x)=1,那么a^(x-1)≡1 (mod x)
然后多次随机a的值,非完美算法加随机化,据说能A掉
我的算法:
1.找出小于50000的所有质数(打表,慢慢找均可)
2.用筛数法,筛去l..r之间的合数
3.找出l..r之间剩余的质数
代码如下(删去打表部分(共29kb)):
核心代码:
2 fillchar(v,sizeof(v),1);
3 for i:=1 to 5133 do if prime[i]>t then break
4 else
5 begin
6 m:=prime[i];
7 n:=l-(l mod m);
8 while n<l do n:=n+m;
9 if n>r then continue;
10 while (n<=r)and(maxlongint-n>=m) do
11 begin
12 v[n-l]:=false;
13 n:=n+m;
14 end;
15 if (n-l<=1000000) then v[n-l]:=false;
16 end;
17 all:=0;
18 for i:=l to r do
19 begin
20 if v[i-l] then inc(all);
21 end;
三题纯属数学题
看了老师给的题解的算法,觉得不好,没我的方法好。
每次只关注某一位数,每次只计算某一位上的和,累加即得最终答案。
代码如下:
2 s:string;
3 function jjj(a,b:int64):int64;
4 begin
5 jjj:=((a+b)*(b-a+1)) div 2;
6 end;
7 begin
8 assign(input,'count.in');reset(input);
9 assign(output,'count.out');rewrite(output);
10 readln(n);
11 str(n,s);
12 k:=10;
13 r:=(n div 10)*jjj(1,9)+jjj(1,ord(s[length(s)])-ord('0'));
14 for i:=length(s)-1 downto 1 do
15 begin
16 k:=k*10;
17 t:=n div k;
18 z:=ord(s[i])-ord('0');
19 m:=t*(k div 10)*jjj(1,9)+jjj(1,z-1)*(k div 10)+((n mod (k div 10))+1)*z;
20 r:=r+m;
21 end;
22 writeln(r);
23 close(output);
24 close(input);
25 end.
26
四题么...那就做不来了...无视之!