Pascal转C++

这篇博客详细介绍了如何将Pascal编程语言的代码转换为C++,涵盖了memset的使用、for循环、max和min的实现,以及结构体、队列操作、字符处理、排序算法和优先队列等内容,并提供了多个示例题目的解决方案,帮助读者理解两种语言的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Pascal转C++练习题

By Jiang

下面是题目,测试数据可以下载 http://download.youkuaiyun.com/detail/jiangzh7/4838315 



题1之前:

1.     掌握memset用法(头文件cstring)

跟Pascal的fillchar一样,带入三个参数,memset(数组,值,大小),举个例子,将数组a全部赋值为0:memset(a,0,sizeof(a));  中间的值和Pascal一样,可以带十六进制,C++中以0x开头的为十六进制数(Pascal是$),如:

     C++                                 Pascal

memset(a,0x07,sizeof(a))         fillchar(a,sizeof(a),$7);

 

2.     for循环

for(赋初值(即循环之前干的事); 继续循环的条件 ;每循环一次后干的事)

如从1~n循环

for(int i=1;i<=n;i++)

如(动规中)从1~n循环,每次01滚动

for(int i=1,int t=0;i<=n;i++,t=1-t)

解释一下,上面这一大句就是首先定义一个i赋值为1,定义一个t赋值为0,然后循环条件不再多说,后面i++不解释,t=1-t就可以实现01滚动(t=0时1-t=1,t=1时1-t=0),这样调用f[t]就相当于调用f[i%2]或者f[i&2]了(&是位运算‘与’)

 

3.     max和min的写法,掌握问号表达式

当然可以学Pascal那样写一个函数

int max(int a,int b)
{
    if(a>b) return a;
    return b;
}

C++有一个问号表达式,格式是  a?b:c,表示如果a是true,那么就执行并返回b,否则返回c,这样刚才的函数就可以写成

int max(int a,int b)
{ return a>b?a:b; }


基于这个,我们写min和max又何必写成函数呢?就可以用宏来解决,就可以写成(宏的定义属于程序的预处理,要加在程序最开头、头文件之下)

#define max(a,b) a>b?a:b;

但是,上面这样是错误地,比如我们调用max(1+2,1+1),它就会直接替换成1+2>1+1?1+2:1+1,按照运算顺序就成了1+((2>1+1)?1+2:1+1),所以最后就会出错,应该加上括号,写成

#define max(a,b) (a)>(b)?(a):(b)

我们在调用一下max(2,1)*3,就直接替换成了2>1?2:1*3,最后的答案是2!看看运算顺序((2>1)?2:1*3),但是我们期待的顺序是((2>1)?2:1)*3,所以在最外面加上括号也是必须的!标准写法应为

#define max(a,b) ((a)>(b)?(a):(b))

同理可以写出min的

#define min(a,b) ((a)<(b)?(a):(b))

 

4.     其他基本语法



造路行动(road.pas/c/cpp/in/out)

题目描述

学校某日突发奇想,要造个小公园。但是,公园造造简单,最麻烦的就是路了。学校张榜:谁设计一个方案,材料费最小,那么,他就获得1000奖学金。鄙人想去,但是作业铺天盖地,根本没时间啊。只好到网上来求助……
各路英雄,帮帮忙吧。

输入格式

第1行,二个数,N,M。N表示公园有N个景点,M表示规划的可以造路的路的条数
接下来M行,每行3个数:X,Y,A。表示第X个景点和第Y个景点之间可以造路,材料费为A。(第X个景点和第Y个景点之间可以造路,也就是说第Y个景点和第X个景点之间也可以造路)。
当然,不会出现孤立的景点。可能有重边!!!矩阵先判断再存
数据范围:0 <N<=1000,0<M<=N*(N-1),0 <X,Y<=N,0 <A<32768。

输出格式

一个数,表示最少的材料费。

样例输入

8 13

1 7 1

1 2 9

1 6 9

2 8 2

2 3 9

3 8 3

3 4 9

4 8 4

4 5 9

5 7 5

5 6 9

6 7 6

7 8 7

样例输出

28







题2之前:

1.     Pascal的Record在C++中如何定义?C++中是结构体struct

struct node{int x,y,z;};

这样就定义了一个名为node的类型,包含x,y,z三个longint

操作和Pascal几乎一样,比如

node a;//定义一个a,为node类型

a.x=1; a.y=2; a.z=3;

2.     stl队列操作

加上头文件#include<queue>,由于是stl,要开放using namespace std;

声明:

queue<node> q;

就开了一个可以储存node的队列,下面对比一下C++和Pascal要好理解些

 

C++

Pascal

声明

queue<node> q;

q:array[0..maxn] of node;

入队

q.push(x);

procedure inq(node x)

begin

  inc(r);  q[r]=x;

end;

取队首第一个

node x=q.front();

var x:node;

x=q[l+1];

第一个弹出

q.pop();

inc(l);

判断队空

q.empty()  队不为空返回true

l<r  队不为空时为true

    宽搜找到答案用exit(0);结束整个程序,需要包含头文件cstdlib

3.     字符操作

读入数据时候涉及到字符操作,用%c读入单个字符,比如读入单个字符到ch可写成

先定义char ch;

scanf(“%c”,&ch);

判断ch是否为’1’,应写为if(ch==’1’)...

注意是两个等号!1由于是单个字符,用单引号!

读入字符串用%s,定义为char数组

char ch[100];//定义一个长度最大为100的字符串数组

scanf(“%s”,ch);

没有分号了,因为ch为一个数组,ch就表示ch[0]的地址,如果不会字符操作,参考下面的读入模块



题目:紧急援救(bfs.pas/c/cpp/in/out)

题目描述

话说2007年8月5日,Mike博士神秘失踪了,最后发现是被外星人绑架了,幸好外星人目前还是在地球上活动,并且知道外星人不了解地球,幸好,Milk博士身上有无线信号发送装置,我们终于确定了他的位置,必须赶快到那里去救他。
根据无线信号发送装置,我们确定出一张地图,为了尽快寻找到Mike博士,于是这个光荣和艰巨的任务便交给了你,编写程序,通过使用一张地图帮助研究所确定从研究所出发找到Mike博士最短距离。
数据范围: n<=1000

输入格式

第一行为n
第二行为n*n的地图(其中0表示通路,1表示死路)
最后两行每行有两个数字,分别表示研究所的坐标和博士信号所在的位置。

输出格式

一个数字k,表示从研究所出发找到Milk博士的最短距离。

样例输入

10

0100110100

0001110010

1000000001

1000100011

0000101100

1000001100

1001010011

0000010100

0101010000

1001000001

1 7

10 2

样例输出

14







题3之前:

果子合并写法很多,可以用双队列(上一题就是队列操作,所以不再使用),练习一下堆

 

堆在C中为heap,但是由于其操作过于繁琐(有兴趣的自己百度看看),所以在C++中出现了一个基于队列的东东,叫做优先队列,可以直接把它当做堆就行了

 

头文件,既然是基于队列的,那么头文件不用说,是

#include<queue>

 

队列的声明是queue<类型> q;而优先队列就要在前面加上优先的单词priority,定义为

priority_queue<类型> q;

 

比如 果子合并这一题就需要定义priority_queue<int>q;//默认大根堆

 

还是列一个表,但是Pascal的就不打了(我不会了。。。)

 

C++表达式

头文件

#include<queue>

定义

大根堆

priority_queue<int> q;

由于默认就是大根堆,所以不需要家任何参数,或者可以写全

priority_queue<int,vector<int>,less<int> > q;

注意,最后两个‘>’间必须有一个空格,不然会让编译器误认为是位运算右移符号‘>>’

vector是动态数组,一般不推荐使用(操作不直观,某些时候会变慢)

好像只有优先队列是相反的,大根堆要用less(英文是‘更小’)定义

小根堆

这里就必须要带上参数了

priority_queue<int,vector<int>,greater<int> > q;

同理,小根堆用greater定义

入队

q.push(x);

取队首元素

int x=q.top();//唯一不同之处

弹出队首

q.pop();

 

 

然后还有排序,排序会用到算法库(头文件algorithm),算法库的详解可以看《C++ Primer》一书,这里只说说sort,也就是排序

 

如果我们需要排序的为一个数组a,从1~n排序,从小到大

sort(a+1,a+1+n);//默认是从小到大

第一个参数a+1表示a数组中a[1]的地址,等同于&a[1],a+1+n表示a数组中a[n+1]的地址,等同于&a[n+1],由于C++的stl全部采用左闭右开的区间,所以上面的右界应是a[n+1]。那么上面一句话就等同于sort(&a[1],&a[n+1]);但是不推荐,后面a[n+1]容易打成a[n]!

 

如果要从大到小就需要写一个比较函数,假设定义为cmp,就写成

sort(a+1,a+1+n,cmp);

在调用之间定义比较函数cmp

bool cmp(int a,int b) { return a>b; }

 

基于比较函数,我们就可以很轻松地写出双关键字排序了,假设我们读入n组数据,每组有x,y两个数,按照x从大到小排序,x相等时按照y从小到大排序

先定义结构体 struct node{int x,y;};然后用node定义数组a,读入数据

sort(a+1,a+1+n,cmp);

在这之前定义比较函数

bool cmp(node a,node b)

{

   if(a.x==b.x) return a.y<b.y;

   return a.x>b.x;

}

 

以此类推就可以写出n关键字排序了

 

在用sort的时候根本不用担心效率问题,它是融合了几种排序算法,是永远卡不到的(除非本来就要超时。。。。)


合并果子(fruit.pas/dpr/c/cpp/in/out)

【问题描述】

    在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。

    每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。

    因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

    例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。

【输入文件】

    输入文件fruit.in包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。

【输出文件】

    输出文件fruit.out包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。

【样例输入】

3
1 2 9

【样例输出】

15

【数据规模】

对于30%的数据,保证有n<=1000:
对于50%的数据,保证有n<=5000;
对于全部的数据,保证有n<=10000。







题4之前:

前面最小生成树已经练了矩阵,这一题就spfa,用链表写!

链表操作要用到前面所说的结构体,就像Pascal会用到Record一样。

比如我们定义一个链表,需要储存点y,权值z,和下一个指针,就要写成

 

C++

Pascal

定义

struct link{int y,z;link* next;};

type

pnode^=tnode;

  tnode=record

y,z:longint;

next:pnode;

  end;

//应该就是这样吧。。。。

声明一个链表

link *head[MAXN];

first:array[0..maxn] of pnode;

插入

void insert(int x,int y,int z)

{

link *node=new link;

node->y=y;node->z=z;

node->next=head[x];

head[x]=node;

}

procedure insert(x,y,z:longint);

var p:pnode;

begin

  new(p);

  p^.y:=y;p^.z:=z;

  p^.next=first[x];

  first[x]=p;

end;

判断指针node是否为空,不为空返回true

if(node)

//在C++中只要一个不为0的值就可作bool返回true

if(node<>nil)

说明

在C++中,在变量名之前加一个*说明该变量是一个地址,加星号表示引用其内容

 

 

C++中结构体用’.’指向内部元素,如a.x

如果是链表中,指针就要变为’->’,如node->x

Pascal同C++,Record也用’.’指向内部元素,如a.x

Pascal中地址指向则变为’^.’,如node^.x




题目:星门跳跃(jump.pas/c/cpp/in/out)

题目描述

在EVE游戏中,宇宙被划分成为许多区域,每个区域中都有数目不定的星门,可以通过星门来跳跃到特定的区域(星门是双向的)。

现在你正参与BBE联军与MLGBD联盟的会战,但由于飞船受损,需要尽快回到后方的友军空间站进行维护。

试编写程序,计算出所须的最短的返回空间站时间。

为了简化问题,我们约定飞船所在的位置为区域1,空间站所在的位置为区域N。

 

问题规模:

对于100%的数据,1<N<=10000,1<M<20000,1<=X[],Y[]<=N,1<=Z[]<=100;

输入格式

第1行,两个整数N,M,分别为区域的总数和星门的总数;

第2..M+1行,每行三个整数X[i],Y[i],Z[i],分别为星门连接的两个区域,以及跳跃所需时间;可能有重边!

输出格式

一个整数,返回空间站所需的最短时间。无法返回输出’NO’

样例输入

5 3

1 4 5

4 5 1

1 2 7

样例输出

6


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值