0 / 前言
这是个人在程序设计中积累的小技巧
1 / 输出时补零
printf("%03d", x);
将3换成要补充的位数。e.g. 输出 03:09
printf("%02d:%02d", 3, 9);
2 / Bitwise Exhaustive Search
这道题给出的一个方法
当我们面临的问题是选与不选的时候可以用这种方法搜索
把二进制中的每一位看作使一个选择,0 就是不选,1 就是选
#include <iostream>
using namespace std;
const int N = 30;
int n, ans = 0x3f3f3f3f * 2;
int a[N];
int main(void)
{
cin >> n;
for(int i = 0; i < n; i++)
cin >> a[i];
for(int i = 0; i < 1 << (n - 1); i++)
{
int orsum = 0;
int xorsum = 0;
for(int j = 0; j <= n; j++)
{
if(j < n)
orsum |= a[j];
if(j == n || (i >> j & 1))
xorsum ^= orsum, orsum = 0;
}
ans = min(ans, xorsum);
}
cout << ans;
return 0;
}
3 / 前缀异或 (prefix-xor)
[
l
,
r
]
[l, r]
[l,r] 区间的异或为 pre[r] ^ pre[l - 1]
;
原理:两个相同的数异或为0, 0异或任何数不变;
int pre[N], a[n];
for(int i = 1; i <= n; i++)
cin >> a[i], pre[i] = pre[i - 1] ^ a[i];
4 / 关于小数的读入
计算机在算小数时是会丢精度的,要想得到精确值可以用整数模拟
scanf("%d.%d", a, b);
这样可以的到精确的整数和小数部分;
注意 :直接 scanf("%lf", f);
在转换成整数也是要丢精度的
作者就曾被卡过
5 / 移项
Given an array
寻找 a[j] - a[i] = j - i
其中 i < j
我是想了好久也没有想出来
结果看答案才发现移项巧妙的问题变得Very Easy
a[j] - j = a[i] - i
orz
6 / 括号序列
()((())(()))
一个合法的括号序列必须满足 (好像也是充要条件)
1.左括号等于右括号
2.任意位置上前面的左括号数量大于等于右括号的数量
7 / 绝对值不等式
这个不等式很重要!!!
∣
∣
x
∣
−
∣
y
∣
∣
≤
∣
x
−
y
∣
≤
∣
x
∣
+
∣
y
∣
||x|-|y| |\le |x-y|\le|x|+|y|
∣∣x∣−∣y∣∣≤∣x−y∣≤∣x∣+∣y∣
A Nice Problem
8 / 从1开始的下标体系下的一个完系
问题:设今天星期二,问 2021 天后星期几?
我们很容易注意到一周七天所有只要模七就行了
然而 (2 + 2021) % 7
的结果是在
0
−
6
0-6
0−6 之间,是模7的一个最小剩余系
你可能会说在结果上加上一个1不就完了,但是考虑 (2 + 5) % 7 + 1
等于1,但是我们期望是星期天.
经过观察我们发现只需要让括号里的被模的数减一结果再加一就能构造出 1 − 7 1-7 1−7的一个完系。
(2 + 2021 - 1) % 7 + 1 == 7 所以是星期天
我们可以再进行化简
2 + 2021 % 7 == 7
一般形式就是
(
a
+
b
−
1
)
%
m
+
1
=
=
a
+
b
%
m
(a + b - 1) \% m +1 == a + b \%m
(a+b−1)%m+1==a+b%m
9 /非负整数的向上取整
A
B
(
A
,
B
∈
N
)
\frac {A}{B} \ \ \ (A,B \in N)
BA (A,B∈N) 向上取整: (A + B - 1) / B;
仅仅适用于非负整数
因为负数向上取整就是截断 A / B
未完待续