刷算法题的一些Trick
1 字符串的输入
在读字符串的时候,一般建议这么写
char str[N]; //字符数组
scanf("%s",str); //因为str可以当作指针,所以不用&
puts(str);
字符串作为函数参数的时候
void func(char str[]){
// 操作就像字符数组一样就行
for(int i = 0; str[i]; i++) printf("%c",str[i]); //输出就用%c没问题
}
关于scanf读入单个字符
//建议这么写
char op[2];
scanf("%s",op);
printf("%c",op[0]);
单个字符读入为什么不取%c呢,因为scanf读单个字符,会把空格回车等乱七八糟的读入,%s会忽略这些。
2 取模的性质
(a+b)%c = (a%c+b%c)%c
(a*b) % c = [(a%c) * (b%c)] % c
3 上下取整以及四舍五入
C语言中下取整直接a/b,因为int直接删掉小数点后几位
上取整a+b-1/b
四舍五入,只说小数点后的,比如对float a小数点后一位四舍五入-----> int a+0.5,float a--->printf("%.2f", a+0.05);
4 取模
C++中,直接取模整数会得到正余数,负数会得到负余数。
为了统一得到正余数,可以自定义取模函数
// 求正余数
int get_mod(int a, int b)
{
return (a % b + b) % b;
}
5 cin cout加速
最好还是用scanf和printf吧...这次做acwing1270用cin,cout被卡TLE了
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
6 取中位数
如果数组从0开始存
sort(a,a+n);
int mid = a[n/2]; // n/2取下整,不论奇数偶数都会取到中位数
如果数组从1开始存
sort(a+1,a+n+1);
int mid = a[(n+1)/2];
7 最大公约数(gcd) 最小公倍数(lcm)
// 欧几里得算法 -- 辗转相除法
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
8 同余的判断
假设我有a和b两个数,要判断他们是否同余,正常人常常这么想a%m==b%m,但是有时候上面的做法不一定正确,原因是可能因为a,b有负数的存在,导致求余的结果正负不一致结果错误,常常要改成(a%m+m)%m == (b%m+m)%m
这样写又有点太麻烦了,所以建议写成下面这个形式:
(a - b) % m == 0

浙公网安备 33010602011771号