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);