【不定期更新】琐碎知识点及注意事项总结
1.在使用sort函数对元素类型为结构体的数组进行排序时,可以在结构体内部对比较运算符进行重载。
例如,对结构体按照第一个关键字进行排序:
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN (100000+5)
struct A{
int x,y;
bool operator < (const A& srt)const{return x<srt.x;};
};
A a[MAXN];
int n;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
}
sort(a,a+n);
for(int i=0;i<n;i++){
printf("%d %d\n",a[i].x,a[i].y);
}
return 0;
}
2.运算符优先级
由表中的说明我们可以看出来,四则运算符号的优先级是高于位运算的优先级的。
所以,(x+y)>>1+1;和((x+y)>>1)+1;的运算结果是截然不同的。一定要加以注意。
3.二分查找需要注意的地方
(I)二分求最小值最大(符合条件的值均在左侧区间,求左侧区间的右端点):
int L=0,R=MAXN;//MAXN<=10^7时在算法竞赛中可确保程序在1s内运行结束
while(L<R){
int MID=(L+R)>>1+1;
if(check(MID))L=MID;
else R=MID-1;
}
(II)二分求最大值最小(符合条件的值均在右侧区间,求右侧区间的左端点):
int L=0,R=MAXN;//MAXN<=10^7时在算法竞赛中可确保程序在1s内运行结束
while(L<R){
int MID=((L+R)>>1);
if(check(MID))R=MID;
else L=MID+1;
}
4.为规范本人的代码书写,宏定义中一定要注意被定义式要加括号,如下:
#define MAXN (100000+5)
#define CLR(x) (memset(x,0,sizeof(x)))
5.结构体中,对变量的定义是有严格顺序的,加入一次性给结构体赋值,需严格按照结构体定义的顺序赋值,如下:
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN (100000+5)
struct A{
int x,y;
bool operator <(const A& srt) const{return x<srt.x;}
};
A a[MAXN];
int n;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
a[i]=(A){x,y};
}
sort(a,a+n);
for(int i=0;i<n;i++){
printf("%d %d\n",a[i].x,a[i].y);
}
return 0;
}
6.有理数计算的避免:
若方程式为:x/a,按实数运算;
假设我们已知a的取值范围是[0,10];
我们可以让x乘上0~10的最小公倍数,这样将分母a约掉,以避免x/a的有理数计算。
7.四舍五入:
由于c语言中没有四舍五入函数,只有向下取整函数floor与向上取整函数ceil,所以我们可以通过以下方式实现:使用floor(x+0.5);
floor()函数包含在<cmath>头文件下。
8.以x为底y的对数:
我们知道任何对数都可以转化为以10为底的对数之间的商,以10为底的对数函数是log10(),所以我们可以这样实现:log10(y)/log10()x;
log10()函数包含在<cmath>头文件下。
9.isdigit() 函数
这个函数用来检查是否一个字符是十进制数字字符或EOF。
十进制数字为:0 1 2 3 4 5 6 7 8 9
函数返回值非0,当被判别字符为十进制数字字符。
例:
/* isdigit example */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main ()
{
char str[]="1776ad";
int year;
if (isdigit(str[0]))
{
year = atoi (str);
printf ("The year that followed %d was %d.\n",year,year+1);
}
return 0;
}
Output
The year that followed 1776 was 1777
10.lower_bound(x,y,z)和upper_bound(x,y,z)
这两个函数的作用如下:
对于一个有序递增序列,序列第一位的地址是x,最后一位的地址是y,我们要寻找一个子序列,这个子序列的所有元素值均为z。
此时,lower_bound(x,y,z)返回这个子序列的第一个元素的下标,upper_bound(x,y,z)返回这个子序列的最后一个元素的下标加1。
lower_bound(x,y,z)和upper_bound(x,y,z)均包含在<algorithm>头文件下。