PAT做题过程中的一些方法技巧总结

5 篇文章 0 订阅
2 篇文章 0 订阅

1.格式化输出整数

例子:

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174

 printf("%04d - %04d = %04d\n",max,min,n);不满足的前面补0。用%04d即可。%04d就是不足4位数前面补0的意思。

比用cout输出要方便:

void print(int n){
//    if(n>0&&n<10)
//        cout<<"000"<<n;
//    else if(n>=10&&n<100)
//        cout<<"00"<<n;
//    else if(n>=100&&n<1000)
//        cout<<"0"<<n;
//    else
//        cout<<n;
}

2.四舍五入

 int c=(int)((b-a)/100+0.5);//1.2+0.5==>1,   1.5+0.5==>2

3.加速cin,cout

在输入输出很大时可以加上这两句:

ios::sync_with_stdio(false);

cin.tie(flase);

注1:endl开销很大,可用‘\n’代替

注2:在pat中,输出一行空行,用printf("\n");会报格式错误,而cout<<"\n"就没事,很奇怪,先记在这。

血的教训:PAT甲级1013题,dfs+邻接表解决

要求:

就用cin,cout,不作任何处理

 

结果就ac了

4.字符串分割

4.1 用scanf(只能输入字符串的时候)

例如:01:01:06:01

scanf("%d:%d:%d:%d", &data[i].month, &data[i].day, &data[i].hour, &data[i].minute);

4.2 用string类

涉及到string类的两个函数find和substr: 

string本身没有提供切割的方法,但可以使用stl提供的封装进行实现或者通过c函数strtok()函数实现。
1、find函数 
原型:size_t find ( const string& str, size_t pos = 0 ) const; 
功能:查找子字符串第一次出现的位置。 
参数说明:str为子字符串,pos为初始查找位置。 
返回值:找到的话返回第一次出现的位置,否则返回string::npos

2、substr函数 
原型:string substr ( size_t pos = 0, size_t n = npos ) const; 
功能:获得子字符串。 
参数说明:pos为起始位置(默认为0),n为结束位置(默认为npos) 
返回值:子字符串 

5.读取字符串含空格或换行等

虽然可以使用 cin 和 >> 运算符来输入字符串,但它可能会导致一些需要注意的问题。
当 cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读,当它读取到下一个空白字符时,它将停止读取。以下面的语句为例:

cin >> namel;

可以输入 "Mark" 或 "Twain",但不能输入 "Mark Twain",因为 cin 不能输入包含嵌入空格的字符串。

为了解决这个问题,可以使用一个叫做 getline 的 C++ 函数。此函数可读取整行,包括前导和嵌入的空格,并将其存储在字符串对象中。
getline 函数如下所示:

 在<string>中的getline函数有四种重载形式:

istream& getline (istream&  is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);
istream& getline (istream&  is, string& str);

istream& getline (istream&& is, string& str);
读取的istream是作为参数is传进函数的。读取的字符串保存在string类型的str中。

函数的变量:

is    :表示一个输入流,例如 cin。

str   :string类型的引用,用来存储输入流中的流信息。

delim :char类型的变量,所设置的截断字符;在不自定义设置的情况下,遇到’\n’,则终止输入。

有用实例:

while(getline(cin,line))

(注意:这里默认回车符停止读入,按Ctrl+Z(Windows)(Ctrl+D(Linux))或键入EOF(参考MSDN)回车即可退出循环。)

6.计算两个时间的间隔

例如:起:01:01:06:01  终:01:01:08:03 间隔:122分钟,若是跨天跨月跨年,再去计算会十分麻烦,此时就可以找一个基准参照时间

例如00:00:00到dd:hh:mm,统统转化为分钟来计算,data[i].time = data[i].day * 24 * 60 + data[i].hour * 60 + data[i].minute;

两个时间都转为相对00:00:00的时间间隔后再相减,就是最后两者的时间间隔。

7.由二叉树的先序和中序得到后序,或者构造一颗二叉树

void postorder(int inL,int inR,int perL,int perR){
	if(inL>inR)//perL>perR也行
		return;
	int root=per[perL],k=0;
	while(k<inR&&in[k]!=root)
		k++;
	int leftnum=k-inL;
	postorder(inL,k-1,perL+1,perL+leftnum);//左子树递归(中序跟k的位置直接有关,先序跟k无直接关系,而是由中序k-inL得到左子树所含结点数,再间接可得位置)
	postorder(k+1,inR,perL+leftnum+1,perR);//右子树递归(同理)
	post.push_back(root);//打印或放入后序队列
}
void postorder(int root,int start,int end){//先序提供根结点信息root,左右子树大小的信息由中序的start和end提供
	if(start>end)
		return;
	int k=0;
	while(k<end&&per[root]!=in[k])//找到中序的根结点位置
		k++;
	postorder(root+1,start,k-1);
	postorder(root+1+k-start,k+1,end);//先序是根左右的结构,其右子树的根结点的位置必须先知道左子树大小,而左子树的大小有必须得根据中序得到
	post.push_back(per[root]);//打印或放入后序队列
}

构造二叉树写法:

Node *create(int postL,int postR,int inL,int inR){
	if(postL>postR)//相等时也成立
		return NULL;
	Node *root=new Node;
	root->data=post[postR];
	int k;
	for(k=inL;k<=inR;++k){//找到中序数组中左右子树的分割结点
		if(in[k]==post[postR])
			break;
	}
	int numLeft=k-inL;//左子树的结点个数
	root->lchild=create(postL,postL+numLeft-1,inL,k-1);
	root->rchild=create(postL+numLeft,postR-1,k+1,inR);
	return root;
}

 一般取闭区间

postorder(0,0,n-1);

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值