上海大学ACM集训队培训资料全Word文档格式.docx

上传人:b****5 文档编号:19613883 上传时间:2023-01-08 格式:DOCX 页数:13 大小:108.35KB
下载 相关 举报
上海大学ACM集训队培训资料全Word文档格式.docx_第1页
第1页 / 共13页
上海大学ACM集训队培训资料全Word文档格式.docx_第2页
第2页 / 共13页
上海大学ACM集训队培训资料全Word文档格式.docx_第3页
第3页 / 共13页
上海大学ACM集训队培训资料全Word文档格式.docx_第4页
第4页 / 共13页
上海大学ACM集训队培训资料全Word文档格式.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

上海大学ACM集训队培训资料全Word文档格式.docx

《上海大学ACM集训队培训资料全Word文档格式.docx》由会员分享,可在线阅读,更多相关《上海大学ACM集训队培训资料全Word文档格式.docx(13页珍藏版)》请在冰豆网上搜索。

上海大学ACM集训队培训资料全Word文档格式.docx

return0;

运行结果

HelloWorld!

供了很多已经写好的函数(成为C++标准库),我们做的只是拿来用就可以了。

第二行的

“usingnamespacestd;

”是使用标准命名空间,因为我们在程序中用到了在标准命名空间里的函数和对象。

目前可以不了解其具体如何实现,在以后的程序设计中可以再对其进行了解。

在明函数中“cout<

”HelloWorld!

”<

”是在屏幕上打印“HelloWorld!

”,“endl”表明打印完这句话之后需要换行。

如果我们替换引号内的内容,程序的输出就会相应改变。

另外一个C++程序例子

//ourfunc.cpp--definingyourownfunction

#include<

voidsimon(int);

//functionprototypeforsimon()

intmain()

usingnamespacestd;

simon(3);

//callthesimon()function

cout<

"

Pickaninteger:

;

intcount;

cin>

>

count;

simon(count);

//callitagain

Done!

<

endl;

return0;

voidsimon(intn)//definethesimon()function

Simonsaystouchyourtoes"

n<

times."

}//voidfunctionsdon'

tneedreturnstatements

下面试运行情况:

Simonsaystouchyourtoes3times.

512

Simonsaystouchyourtoes512times.

程序中包含了cin语句来从键盘上获取数据。

该程序中包含了除main函数以外的另一个函数simon(),他和main函数定义的格式相同,函数的统一格式如下:

typefunctionname(argumentlist)

statements

注意,定义simon()的代码在main()函数的后面,C++中不允许将函数定义在另一个函数内。

每个函数的定义都是独立的,所有的函数的创建都是平等的。

simon()函数的函数头定义如下:

voidsimon(intn)

以void开头表明simon()没有返回值,因此我们不能类是这样的使用它。

simple=simon(3);

有返回值的函数如下

//convert.cpp--convertsstonetopounds

intstonetolb(int);

//functionprototype

intstone;

Entertheweightinstone:

stone;

intpounds=stonetolb(stone);

stone<

stone="

pounds<

pounds."

intstonetolb(intsts)

return14*sts;

}下面是运行情况:

Entertheweightinsone:

14

14stone=196pounds.

程序通过cin语句给stone提供一个值,然后在main函数中,把这个值传递给stonetolb()函数,这个植被赋给sts之后,stonetolb()用return将14*sts返回给main()。

函数头中的int表明stonetolb()将返回一个整数。

除了int类型之外,C++的内置数据类型还有:

unsignedlong、Iong、unsignedint、unsignedshort、short、char、unsignedchar、signedchar、bool、float、double、longdouble。

对于数据的输入和输出有几道练习题至

二、算法基础

1.什么是算法

算法是完成特定任务的有限指令集。

所有的算法必须满足下面的标准:

a.输入。

由外部题共零个或多个输入量。

b.输出。

至少产生一个输出量。

c.明确性。

每条指令必须清楚,不具模糊性。

d.有限性。

如果跟踪算法的指令,那么对于所有的情况,算法经过有限步以后终止。

e.有效性。

每条指令必须非常基础,原则上使用笔和纸就可以实现

例选择排序

voidSelectionSort(Typea[],intn)

//Sortthearrata[1:

n]intonondecreasingorder.{

for(inti=1;

i<

=n;

i++)

intj=1;

for(intk=i+1;

k<

k++)

if(a[k]<

a[j])j=k;

Typet=a[i];

a[i]=a[j];

a[j]=t;

c1n

c2n

n

c3(ni)

i1

使用该函数时,应将Type替换为C++中的数据类型

3.性能分析

程序P所用时间定义为T(P),T(P)是编译时间和运行时间之和。

下面我们计算一下选择排序运行时所要花费的时间

SelectionSort

cost

times

a[j])

j=k;

a[i]=a[j];

a[j]

c4(ni)

c5ti

c6n

=t;

那么该算法运行的时间

那么,在最坏的条件下,ti的值应该是(ni)

i1

C和n0,使得对于所有的n(nn°

),有f(n)cg(n)。

对于所有n1有62nn22n,所以62nn2(2n)。

当然62nn2(n),但是(n)(2n)。

现然无论是O还是Q,都不能精确的描述一个函数

C1,C2和n°

,使得对于所有的n(nn°

),有&

g(n)f(n)c?

g(n)。

对于n2有3n23n且3n24n,所以3n2(n)

©

记号要比O和Q都要精确。

排列生成器©

(n!

voidPerm(Typea[],intk,intn)

if(k==n){//Outputpermutation.

for(inti-1;

n;

i++)cout<

a[i]<

else//a[k:

n]hasmorethanonepermutation.//Generatetheserecursively.for(inti=k;

i++){

Typet=a[k];

a[k]=a[i];

a[i]=t;

Perm(a,k+1,n);

//Allpermutationsofa[k+1:

n]t=a[k];

对于下面的程序

#include<

voidPerm(inta[],intk,intn)

if(k<

n-1)

inti,t;

for(i=k;

t=a[k];

a[k]=a[i];

a[i]=t;

Perm(a,k+1,n);

a[i]=t;

inta[3]={1,2,3};

Perm(a,0,3);

该程序的运行结果为

123

132

213

321

312

那么,该函数就完成了对一个数组进行全排列的操作下面,分析该程序,我用圆圈代表每次函数的调用每次函数的调用都用序号表示

1.

a:

123

k:

0

6.

213

2

2.

1

7.

231

3.

8.

321

4.

132

9.

5.

10.

312

排列生成器的另外一个版本

他将输出给定n个布尔变量的所有可能的组合

voidPerm(boola[],intk,intn){

if(k==n)

//statement

}else

a[k]=true;

a[k]=false;

}

在上次冬季赛上有这么一道题竞赛真理

JUNNY在经历了无数次学科竞赛的失败以后,得到了一个真理:

做一题就要对一题!

但是要

完全正确地做对一题是要花很多时间(包括调试时间),而竞赛的时间有限。

所以开始做题之前最好先认真审题,估计一下每一题如果要完全正确地做出来所需要的时间,然后选择一些有把握的题目先做。

当然,如果做完了预先选择的题目之后还有时间,但是这些时间又不足以完全解决一道题目,应该把其他的题目用贪心之类的算法随便做做,争取“骗”一点

分数。

根据每一题解题时间的估计值,确定一种做题方案(即哪些题目认真做,哪些题目“骗”分,哪些不做),使能在限定的时间内获得最高的得分。

INPUTFORMAT:

从标准输入(cin,scanf等)读入数据。

数据有多组,先输入K(K组数据)。

每组第一行有

两个正整数N和T,表示题目的总数以及竞赛的时限(单位秒)。

以下的N行,每行4个正

整数W1i、T1i、W2i、T2i,分别表示第i题:

完全正确做出来的得分,完全正确做出来所花费的时间(单位:

秒),“骗”来的分数,“骗”分所花费的时间(单位秒)。

其中,3<

N<

30,2<

T<

1080000,1wW1i、W2i<

30000,1<

T1i、T2i<

T。

OUTPUTFORMAT:

直接把所求得的最高得分输出。

数据之间需换行。

SAMPLEINPUT:

2

410800

18360031800

224000123000

28600003000

328000246000

37200

50540010900

50720010900

SAMPLEOUTPUT:

50

70

下面我们对问题进行简化。

我们只要考虑是做题还是不做题。

数据只有一组,先输入K(K组数据)。

每组第一行

有两个正整数N和T,表示题目的总数以及竞赛的时限(单位秒)。

以下的N行,每行2个

正整数Wi、Ti,分别表示第i题:

做出来的得分和做出来所花费的时间(单位:

秒),OUTPUT

FORMAT:

直接把所求得的最高得分输出。

510

120

415

score+=t[x][1];

time+=t[x][0];

if(time<

=tSum)

{if(score>

m){m=score;

boola[30];

intn,c;

cin>

n>

tSum;

m=0;

for(c=0;

c<

c++){cin>

t[c][0];

t[c][1];

f(a,0,n);

cout<

m<

work()函数内,然后work函数找到在时间范围内的

就能得到更好的程序cTime){if(k<

n){dfs(k+1,n,cScore,cTime);

dfs(k+1,n,cScore+t[k][1],cTime+t[k][0]);

else

intn,c;

if(cTime<

cin>

m=0;

if(cScore>

m)

for(c=0;

c++)

m=cScore;

dfs(0,n,0,0);

这个程序就是深度优先搜索,如果n非常大,递归调用的次数是非常惊人的,达到2n次。

 

为了减少递归的次数,我们可以采取剪枝的手段,在递归下一次前判断是否可行。

如果肯定不能就停止递归,节省时间。

m=cScore

intm;

intt[20][2];

inttSum;

voiddfs(intk,intn,intcScore,int

cTime)

if(k<

n)

dfs(k+1,n,cScore,cTime);

tSum)

dfs(k+1,n,cScore+

t[k][1],cTime+t[k][0]);

为了达到更好的剪枝效果,可以在搜索前对数据进行排序。

竞赛真理原题也可用这种思想去解。

更复杂的算法将在以后进行讲解.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 哲学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1