PASCAL算法知识题~~高分~紧急~

我的老师给我出了几张纸的题目,求你们帮我添一添;

①穷举

1:什么是穷举?

2:穷举的好处,以及常用的地方?

3:归纳一些穷举的题目的特征。找出其缺点。

4:弥补或修正穷举法的技术有哪些?各找一例说明。

5:如果能通过穷举找到一个数学算式,就试图找对该公式。(重要)

6:记录几个穷举的程序中的段子。

每个算法有以上的 6题,要写的算法有:穷举、递归(没递推)、回朔、贪心。
就是4个算法,类似上面的6道题目。总共24道题目。做的我满意的,我会追加很多分的~~~~~~~~~~~~
谢谢………………

很紧急…………
帮帮我~~~~~~~~~~

6.1 穷举策略的概念

所谓枚举法,指的是从可能的解的集合中一一枚举各元素, 用题目给定的检验条件判定哪些是无用的,哪些是有用的。能使命题成立,即为其解。

有些问题可以用循环语句和条件语句直接求解,有些问题用循环求解时循环次数太多,无法编写程序,怎么办?下面是用“千军万马过独木桥,适者存”的方式实现穷举策略的。

6.2 典型例题与习题

例1.将2n个0和2n个1,排成一圈。从任一个位置开始,每次按逆时针的方向以长度为n+1的单位进行数二进制数。要求给出一种排法,用上面的方法产生出来的2n+1个二进制数都不相同。

例如,当n=2时,即22个0和22个1排成如下一圈:

比如,从A位置开始,逆时针方向取三个数000,然后再从B位置上开始取三个数001,接着从C开始取三个数010,...可以得到000,001,010,101,011,111,110,100共8个二进制数且都不相同。

程序说明:

以n=4为例,即有16个0,16个1,数组a用以记录32个0,1的排法,数组b统计二进制数出现的可能性。

程序清单

PROGRAM NOI00;
VAR
A :ARRAY[1..36] OF 0..1
B :ARRAY[0..31] OF INTEGER;
I,J,K,S,P:INTEGER;
BEGIN
FOR I:=1 TO 36 DO A[I]:=0;
FOR I:=28 TO 32 DO A[I]:=1;
P:=1; A[6]:=1;
WHILE (P=1) DO
BEGIN
J:=27
WHILE A[J]=1 DO J:=J-1;
( A[J]:=1 )
FOR I:=J+1 TO 27 DO ( A[i]:=0 )
FOR I:=0 TO 31 DO B[I]:=0;
FOR I:=1 TO 32 DO
BEGIN
( S:=0)
FOR K:=I TO I+4 DO S:=S*2+A[k];
( B[S]:=1 )
END;
S:=0;
FOR I:=0 TO 31 DO S:=S+B[I];
IF ( S=32 ) THEN P:=0
END;
FOR I:=1 TO 32 DO FOR J:=I TO I+4 DO WRITE(A[J]);
WRITELN
END.

例2:在A、B两个城市之间设有N个路站(如下图中的S1,且N<100),城市与路站之间、路站和路站之间各有若干条路段(各路段数<=20,且每条路段上的距离均为一个整数)。
A,B的一条通路是指:从A出发,可经过任一路段到达S1,再从S1出发经过任一路段,…最后到达B。通路上路段距离之和称为通路距离(最大距离<=1000)。当所有的路段距离给出之后,求出所有不同距离的通路个数(相同距离仅记一次)。
例如:下图所示是当N=1时的情况:

从A到B的通路条数为6,但因其中通路5+5=4+6,所以满足条件的不同距离的通路条数为5。

算法说明:本题采用穷举算法。
数据结构:N:记录A,B间路站的个数
数组D[I,0]记录第I-1个到第I路站间路段的个数
D[I,1],D[I,2],…记录每个路段距离
数组G记录可取到的距离
程序清单:
program CHU7_6;
var i,j,n,s:integer;
b:array[0..100] of integer;
d:array[0..100,0..20] of integer;
g:array[0..1000] of 0..1;
begin
readln(n);
for i:=1 to n+1 do
begin
readln(d[i,0]);
for j:=1 to d[i,0] do read(d[i,j]);
end;
d[0,0]:=1;
for i:=1 to n+1 do b[i]:=1;
b[0]:=0;
for i:=1 to 1000 do g[i]:=0;
while b[0]<>1 do
begin
s:=0;
for i:=1 to n+1 do
s:= s+d[i,b[i]];
g[s]:=1;j:=n+1;
while b[j]=d[j,0] do j:=j-1;
b[j]:=b[j]+1;
for i:=j+1 to n+1 do b[i]:=1;
end;
s:=0;
for i:=1 to 1000 do
s:=s+g[i];
writeln(s);readln;
end.

2.1 递归的概念

1.概念

一个过程(或函数)直接或间接调用自己本身,这种过程(或函数)叫递归过程(或函数).

如:

procedure a;

begin

.

.

.

a;

.

.

.

end;

这种方式是直接调用.

又如:

procedure b; procedure c;

begin begin

. .

. .

. .

c; b;

. .

. .

. .

end; end;

这种方式是间接调用.

例1计算n!可用递归公式如下:

1 当 n=0 时

fac(n)={n*fac(n-1) 当n>0时

可编写程序如下:

program fac2;

var

n:integer;

function fac(n:integer):real;

begin

if n=0 then fac:=1 else fac:=n*fac(n-1)

end;

begin

write('n=');readln(n);

writeln('fac(',n,')=',fac(n):6:0);

end.

例2 楼梯有n阶台阶,上楼可以一步上1阶,也可以一步上2阶,编一程序计算共有多少种不同的走法.

设n阶台阶的走法数为f(n)

显然有

1 n=1

f(n)={2 n=2

f(n-1)+f(n-2) n>2

可编程序如下:

program louti;

var n:integer;

function f(x:integer):integer;

begin

if x=1 then f:=1 else

if x=2 then f:=2 else f:=f(x-1)+f(x-2);

end;

begin

write('n=');read(n);

writeln('f(',n,')=',f(n))

end.

2.2 如何设计递归算法
1.确定递归公式

2.确定边界(终了)条件

练习:

用递归的方法完成下列问题

1.求数组中的最大数

2.1+2+3+...+n

3.求n个整数的积

4.求n个整数的平均值

5.求n个自然数的最大公约数与最小公倍数

6.有一对雌雄兔,每两个月就繁殖雌雄各一对兔子.问n个月后共有多少对兔子?
7.已知:数列1,1,2,4,7,13,24,44,...求数列的第 n项.
2.3典型例题

例3 梵塔问题

如图:已知有三根针分别用1,2,3表示,在一号针中从小放n个盘子,现要求把所有的盘子

从1针全部移到3针,移动规则是:使用2针作为过度针,每次只移动一块盘子,且每根针上

不能出现大盘压小盘.找出移动次数最小的方案.

程序如下:

program fanta;

var

n:integer;

procedure move(n,a,b,c:integer);

begin

if n=1 then writeln(a,'--->',c)

else begin

move(n-1,a,c,b);

writeln(a,'--->',c);

move(n-1,b,a,c);

end;

end;

begin

write('Enter n=');

read(n);

move(n,1,2,3);

end.

例4 快速排序

快速排序的思想是:先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为1, 处理结束.

程序如下:

program kspv;
const n=7;
type
arr=array[1..n] of integer;
var
a:arr;
i:integer;
procedure quicksort(var b:arr; s,t:integer);
var i,j,x,t1:integer;
begin
i:=s;j:=t;x:=b[i];
repeat
while (b[j]>=x) and (j>i) do j:=j-1;
if j>i then begin t1:=b[i]; b[i]:=b[j];b[j]:=t1;end;
while (b[i]<=x) and (i<j) do i:=i+1;
if i<j then begin t1:=b[j];b[j]:=b[i];b[i]:=t1; end
until i=j;
b[i]:=x;
i:=i+1;j:=j-1;
if s<j then quicksort(b,s,j);
if i<t then quicksort(b,i,t);
end;
begin
write('input data:');
for i:=1 to n do read(a[i]);
writeln;
quicksort(a,1,n);
write('output data:');
for i:=1 to n do write(a[i]:6);
writeln;
end.
3.1 回溯的设计

1.用栈保存好前进中的某些状态.

2.制定好约束条件

例1由键盘上输入任意n个符号;输出它的全排列.

program hh;
const n=4;
var i,k:integer;
x:array[1..n] of integer;
st:string[n];
t:string[n];
procedure input;
var i:integer;
begin
write('Enter string=');readln(st);
t:=st;
end;
function place(k:integer):boolean;
var i:integer;
begin
place:=true;
for i:=1 to k-1 do
if x[i]=x[k] then
begin place:=false; break end ;
end;
procedure print;
var i:integer;
begin
for i:=1 to n do write(t[x[i]]);
writeln;
end;
begin
input;
k:=1;x[k]:=0;
while k>0 do
begin
x[k]:=x[k]+1;
while (x[k]<=n) and (not place(k)) do x[k]:=x[k]+1;
if x[k]>n then k:=k-1
else if k=n then print
else begin k:=k+1;x[k]:=0 end
end ;
end.

例2.n个皇后问题:

program hh;
const n=8;
var i,j,k:integer;
x:array[1..n] of integer;
function place(k:integer):boolean;
var i:integer;
begin
place:=true;
for i:=1 to k-1 do
if (x[i]=x[k]) or (abs(x[i]-x[k])=abs(i-k)) then
place:=false ;
end;
procedure print;
var i:integer;
begin
for i:=1 to n do write(x[i]:4);
writeln;
end;
begin
k:=1;x[k]:=0;
while k>0 do
begin
x[k]:=x[k]+1;
while (x[k]<=n) and (not place(k)) do x[k]:=x[k]+1;
if x[k]>n then k:=k-1
else if k=n then print
else begin k:=k+1;x[k]:=0 end
end ;

end.

回溯算法的公式如下:

3.2 回溯算法的递归实现

由于回溯算法用一栈数组实现的,用到栈一般可用递归实现。

上述例1的递归方法实现如下:

program hh;
const n=4;
var i,k:integer;
x:array[1..n] of integer;
st:string[n];
t:string[n];
procedure input;
var i:integer;
begin
write('Enter string=');readln(st);
t:=st;
end;
function place(k:integer):boolean;
var i:integer;
begin
place:=true;
for i:=1 to k-1 do
if x[i]=x[k] then
begin place:=false; break end ;
end;
procedure print;
var i:integer;
begin
for i:=1 to n do write(t[x[i]]);
writeln;readln;
end;
procedure try(k:integer);
var i :integer;
begin
if k=n+1 then begin print;exit end;
for i:=1 to n do
begin
x[k]:=i;
if place(k) then try(k+1)
end
end;
begin
input;
try(1);
end.

例2:n皇后问题的递归算法如下:

程序1:

program hh;
const n=8;
var i,j,k:integer;
x:array[1..n] of integer;
function place(k:integer):boolean;
var i:integer;
begin
place:=true;
for i:=1 to k-1 do
if (x[i]=x[k]) or (abs(x[i]-x[k])=abs(i-k)) then
place:=false ;
end;
procedure print;
var i:integer;
begin
for i:=1 to n do write(x[i]:4);
writeln;
end;
procedure try(k:integer);
var i:integer;
begin
if k=n+1 then begin print; exit end;
for i:= 1 to n do
begin
x[k]:=i;
if place(k) then try(k+1);
end;
end ;
begin
try(1);
end.

程序2:

说明:当n=8 时有30条对角线分别用了l和r数组控制,

用c数组控制列.当(i,j)点放好皇后后相应的对角线和列都为false.递归程序如下:

program nhh;
const n=8;
var s,i:integer;
a:array[1..n] of byte;
c:array[1..n] of boolean;
l:array[1-n..n-1] of boolean;
r:array[2..2*n] of boolean;
procedure output;
var i:integer;
begin
for i:=1 to n do write(a[i]:4);
inc(s);writeln(' total=',s);
end;
procedure try(i:integer);
var j:integer;
begin
for j:=1 to n do
begin
if c[j] and l[i-j] and r[i+j] then
begin
a[i]:=j;c[j]:=false;l[i-j]:=false; r[i+j]:=false;
if i<n then try(i+1) else output;
c[j]:=true;l[i-j]:=true;r[i+j]:=true;
end;
end;
end;
begin
for i:=1 to n do c[i]:=true;
for i:=1-n to n-1 do l[i]:=true;
for i:=2 to 2*n do r[i]:=true;
s:=0;try(1);
writeln;
end.
7.1 贪心策略的定义

贪心策略是:指从问题的初始状态出发,通过若干次的贪心选择而得出最优值(或较优解)的一种解题方法。

其实,从“贪心策略”一词我们便可以看出,贪心策略总是做出在当前看来是最优的选择,也就是说贪心策略并不是从整体上加以考虑,它所做出的选择只是在某种意义上的局部最优解,而许多问题自身的特性决定了该题运用贪心策略可以得到最优解或较优解。
例1:在n行m列的正整数矩阵中,要求从每一行中选一个数,使得选出的n个数的和最大。

本题可用贪心策略:选n次,每一次选相应行中的最大值即可。

例2:在一个N×M的方格阵中,每一格子赋予一个数(即为权)。规定每次移动时只能向上或向右。现试找出一条路径,使其从左下角至右上角所经过的权之和最大。

本题用贪心策略不能得到最优解,我们以2×4的矩阵为例。 3 4 6
1 2 10

若按贪心策略求解,所得路径为:1,3,4,6;

若按动态规划法求解,所得路径为:1,2,10,6。

例3:设定有n台处理机p1,p2,......pn,和m个作业j1,j2,...jm,处理机可并行工作,作业未完成不能中断,作业ji在处理机上的处理时间为ti,求解最佳方案,使得完成m项工作的时间最短?

本题不能用贪心算法求解:理由是若n=3,m=6 各作业的时间分别是11 7 5 5 4 7

用贪心策略解(每次将作业加到最先空闲的机器上)time=15,用搜索策略最优时间应是14,但是贪心策略给我们提供了一个线索那就是每台处理上的时间不超过15,给搜索提供了方便。

总之:
1. 不能保证求得的最后解是最佳的;
2. 只能用来求某些最大或最小解问题;
3. 能确定某些问题的可行解的范围,特别是给搜索算法提供了依据。

7. 2 贪心策略的特点
贪心算法有什么样的特点呢?我认为,适用于贪心算法解决的问题应具有以下2个特点:

1、贪心选择性质:

所谓贪心选择性质是指应用同一规则f,将原问题变为一个相似的、但规模更小的子问题、而后的每一步都是当前看似最佳的选择。这种选择依赖于已做出的选择,但不依赖于未做出的选择。从全局来看,运用贪心策略解决的问题在程序的运行过程中无回溯过程。关于贪心选择性质,读者可在后文给出的贪心策略状态空间图中得到深刻地体会。

2、局部最优解:

我们通过特点2向大家介绍了贪心策略的数学描述。由于运用贪心策略解题在每一次都取得了最优解,但能够保证局部最优解得不一定是贪心算法。如大家所熟悉得动态规划算法就可以满足局部最优解,但贪心策略比动态规划时间效率更高站用内存更少,编写程序更简单。

7.3 典型例题与习题

例4:背包问题:

有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。
要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。 物品
A
B
C
D
E
F
G

重量
35
30
60
50
40
10
25

价值
10
40
30
50
35
40
30

分析:

目标函数: ∑pi最大
约束条件是装入的物品总重量不超过背包容量:∑wi<=M( M=150)

(1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?
(2)每次挑选所占空间最小的物品装入是否能得到最优解?
(3)每次选取单位容量价值最大的物品,成为解本题的策略。

程序如下:

program beibao;

const
m=150;
n=7;
var
xu:integer;
i,j:integer;
goods:array[1..n,0..2] of integer;
ok:array[1..n,1..2] of real;

procedure init;
var
i:integer;
begin
xu:=m;
for i:=1 to n do
begin
write('Enter the price and weight of the ',i,'th goods:');
goods[i,0]:=i;
read(goods[i,1],goods[i,2]);
readln;
ok[i,1]:=0; ok[i,2]:=0;
end;
end;

procedure make;
var
bi:array[1..n] of real;
i,j:integer;
temp1,temp2,temp0:integer;
begin
for i:=1 to n do
bi[i]:=goods[i,1]/goods[i,2];
for i:=1 to n-1 do
for j:=i+1 to n do
begin
if bi[i]<bi[j] then begin
temp0:=goods[i,0]; temp1:=goods[i,1]; temp2:=goods[i,2];
goods[i,0]:=goods[j,0]; goods[i,1]:=goods[j,1]; goods[i,2]:=goods[j,2];
goods[j,0]:=temp0; goods[j,1]:=temp1; goods[j,2]:=temp2;
end;
end;
end;

begin
init;
make;
for i:=1 to 7 do
begin
if goods[i,2]>xu then break;
ok[i,1]:=goods[i,0]; ok[i,2]:=1;
xu:=xu-goods[i,2];
end;
j:=i;
if i<=n then
begin
ok[i,1]:=goods[i,0];
ok[i,2]:=xu/goods[i,2];
end;
for i:=1 to j do
writeln(ok[i,1]:1:0,':',ok[i,2]*goods[i,2]:2:1);
end.

例5:旅行家的预算问题:

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市,给定两个城市间的距离d1,汽车油箱的容量是c,每升汽油能行驶的距离d2,出发时每升汽油的价格是p,沿途加油站数为n(可为0),油站i离出发点的距离是di,每升汽油的价格是pi。

计算结果四舍五入保留小数点后两位,若无法到达目的地输出“No answer"

若输入:

d1=275.6 c=11.9 d2=27.4 p=8 n=2

d[1]=102 p[1]=2.9

d[2]=220 p[2]=2.2

output

26.95

本问题的贪心策略是:找下一个较便宜的油站,根据距离确定加满、不加、加到刚好到该站。

程序如下:

program jiayou;
const maxn=10001;
zero=1e-16;
type
jd=record
value,way,over:real;
end;
var oil:array[1..maxn] of ^jd;
n:integer;
d1,c,d2,cost,maxway:real;
function init:boolean;
var i:integer;
begin
new(oil[1]);
oil[1]^.way:=0;
read(d1,c,d2,oil[1]^.value,n);
maxway:=d2*c;
for i:=2 to n+1 do
begin
new(oil[i]);
readln(oil[i]^.way,oil[i]^.value);
oil[i]^.over:=0;
end;
inc(n,2);
new(oil[n]);
oil[n]^.way:=d1;
oil[n]^.value:=0;
oil[n]^.over:=0;
for i:=2 to n do
if oil[i]^.way-oil[i-1]^.way>maxway then
begin
init:=false;
exit
end;
init:=true;
end;
procedure buy(i:integer;miles:real);
begin
cost:=cost+miles/d2*oil[i]^.value;
end;
procedure solve;
var i,j:integer;
s:real;
begin
i:=1;j:=i+1;
repeat
s:=0.0;
while( s<=maxway+zero) and (j<=n-1) and (oil[i]^.value<=oil[j]^.value) do
begin
inc(j);
s:=s+oil[j]^.way-oil[j-1]^.way
end;
if s<=maxway+zero then
if (oil[i]^.over+zero>=oil[j]^.way-oil[i]^.way) then
oil[j]^.over:=oil[i]^.over-(oil[j]^.way-oil[i]^.way) else
begin
buy(i,oil[j]^.way-oil[i]^.way-oil[i]^.over);
oil[j]^.over:=0.0;
end
else begin
buy(i,maxway-oil[i]^.over);
j:=i+1;
oil[j]^.over:=maxway-(oil[j]^.way-oil[i]^.way);
end;
i:=j;
until i=n;
end;
begin
cost:=0;
if init then begin
solve;
writeln(cost:0:2);
end else writeln('No answer');
end.

例6:n个部件,每个部件必须经过先A后B两道工序。

以知部件i在A,B 机器上的时间分别为ai,bi。如何安排加工顺序,总加工时间最短?

输入:

5 部件 1 2 3 4 5
ai 3 5 8 7 10
bi 6 2 1 4 9

输出:

34

1 5 4 2 3

本问题的贪心策略是A机器上加工短的应优先,B机器上加工短的应靠后。

程序如下:

program workorder;
const maxn=100;
type jd=record
a,b,m,o:integer;
end;
var n,min,i:integer;
c:array[1..maxn] of jd;
order:array[1..maxn] of integer;
procedure init;
var i:integer;
begin
readln(n);
for i:=1 to n do
read(c[i].a);
readln;
for i:=1 to n do
read(c[i].b);
readln;
for i:=1 to n do
begin
if c[i].a<c[i].b then c[i].m:=c[i].a else c[i].m:=c[i].b;
c[i].o:=i;
end;
end;
procedure sort;
var i,j,k,t:integer;
temp:jd;
begin
for i:=1 to n-1 do
begin
k:=i;t:=c[i].m;
for j:=i+1 to n do
if c[j].m<t then begin t:=c[j].m;k:=j end ;
if k<>i then begin temp:=c[i];c[i]:=c[k];c[k]:=temp end
end;
end;
procedure playorder;
var i,s,t:integer;
begin
fillchar(order,sizeof(order),0);
s:=1;
t:=n;
for i:=1 to n do
if c[i].m=c[i].a then begin order[s]:=i;s:=s+1 end
else begin order[t]:=i;t:=t-1;end;
end;
procedure calc_t;
var i,t1,t2:integer;
begin
t1:=0;t2:=0;
for i:=1 to n do
begin
t1:=t1+c[order[i]].a;
if t2<t1 then t2:=t1;
t2:=t2+c[order[i]].b;
end;
min:=t2;
end;
begin
init;
sort;
playorder;
calc_t;
writeln(min);
for i:=1 to n do
write(c[order[i]].o,' ');
writeln;
end.

参考资料:有书,要不?发[email protected],就回你书

温馨提示:答案为网友推荐,仅供参考
第1个回答  2008-07-30
穷举法(Exhaustive Attack method),又称为强力法

(Brute-force method). 完全试凑法(complete trial-and –

error method)

– 这是对截获的密文依次用各种可能的密钥破译.

– 对所有可能的明文加密直到与截获的密文一致为止.
穷举法用时间上的牺牲换来了解的全面性保证,尤其是随着计算机运算速度的飞速发展,穷举法的形象已经不再是最低等和原始的无奈之举,比如经常有黑客在几乎没有任何已知信息的情况下利用穷举法来破译密码,足见这种方法还是有其适用的领域的

是一种针对于密码的破译方法。这种方法很象数学上的“完全归纳法”并在密码破译方面得到了广泛的应用。简单来说就是将密码进行逐个推算直到找出真正的密码为止。比如一个四位并且全部由数字组成其密码共有10000种组合,也就是说最多我们会尝试10000次才能找到真正的密码。利用这种方法我们可以运用计算机来进行逐个推算,也就是说用我们破解任何一个密码也都只是一个时间问题。

字符类型一般可以分为一下5种
数字型0、1、2、...9等(10个)
大写字母A、B、C、...Z等(26个)
小写字母a、b、c、...z等(26个)
特殊字符~、$、#、@、&、*等(33个)一般较少用
用户自定义字符。
如果一个多位数并且有可能包含以上所有字符的密码的组合方法一定多的惊人,相对来讲破译的时间也会长的没法接受,有时可能会长达数年之久。

当然如果破译一个有8位而且有可能拥有大小写数字、字母、以及符号的密码用普通的家用电脑可能会用掉几个月甚至更多的时间去计算,其组合方法可能有几千万亿重种组合。这样长的时间显然是不能接受的。其解决办法就是运用字典,所谓“字典”就是给密码锁定某个范围,比如英文单词以及生日的数字组合等,所有的英文单词不过10万个左右这样可以大大缩小密码范围,很大程度上缩短了破译时间。

在一些领域为了提高密码的破译效率而专门为其制造的超级计算机也不在少数,例如IBM为美国军方制造的“飓风”就是很有代表性的一个。

穷举的好处在于每次递归都
基于之前计算得到的最优解,因此避免了很多不必要的搜索路径。

贪婪策略利用某一类问题的如下特点:问题可以划分为一系列步骤,每一步的局部最优导致全局最优。可以成功应用这一策略的问题包括,最小生成树,最短路径,fractional
背包问题,找零钱等

参考资料:百度知道

第2个回答  2008-07-30
1穷举就是把所有可能的情况一一列举并检查

2好处是答案完成全面,没有遗漏,常用于数据规模较小,较简单的运算

3缺点是速度缓慢,有一些明显不可能的情况也会被检查

4使用各种其它的算法,做预处理等等本回答被提问者和网友采纳
相似回答