算法
见面与问候

如果两个点从原点开始,都是以1个单位距离/1个单位时间在坐标轴上运动,那么这两个点要么是在某个坐标相遇,要么相差一个点快要相遇,不可能在两个坐标之间相遇。

scanf("%d %c", &x, &op);scanf会读入空格

外层循环为1e5,内层最多循环1e6,内层循环决定了时间复杂度,总共是$O(1e6)$

注意:如果时间刚停止时,两头奶牛刚好碰见,那么时间停止后也会碰见一起 ,遍历要加入判断是否为时间停止后的情况。

镜子

①写dx[],dy[]的时候,注意题目中给的坐标系是怎么建立的,x,y轴向上还是向下。

②当上下左右四个方向分别用0,1,2,3来表示,注意他们方向之间的变换规则。如0和1,2和3可以用将方向^1就可以得到更改后的方向。

③当坐标的移动不是一个单位的时候,可以用向量乘以一个模

char op; op = '\\', ‘\‘是转义字符~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include<iostream>

using namespace std;

const int N = 210, INF = 1e8;

struct Mirror {
int x, y;
char c;
}q[N];

int n;
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

void tamate(char &c) {
if(c == '/') c = '\\';
else c = '/';
}

bool check() {
int d = 1, k = 0;
for(int i = 0; i <= 2 * (n + 1); i ++) {
int id = -1, len = INF; //len变量是因为要找到离它最近的点。
for(int j = 1; j <= n + 1; j ++) {
if(k == j) continue;
if(q[k].x + abs(q[k].x - q[j].x) * dx[d] != q[j].x) continue;
if(q[k].y + abs(q[k].y - q[j].y) * dy[d] != q[j].y) continue;

int t = abs(q[k].x - q[j].x) + abs(q[k].y - q[j].y);
if(t < len) len = t, id = j;
}
if(id == -1) return false;
if(id == n + 1) return true;
k = id;
if(q[k].c == '/') d ^= 1;
else d ^= 3;
}
return false;
}


int main() {
cin >> n;
cin >> q[n + 1].x >> q[n + 1].y;

for(int i = 1; i <= n; i ++)
cin >> q[i].x >> q[i].y >> q[i].c;

if(check())
puts("0");
else {
for(int i = 1; i <= n; i ++) {
tamate(q[i].c);
if(check()) {
cout << i << endl;
return 0;
}
tamate(q[i].c);
}
puts("-1");
}

return 0;
}
信息中继

baoli~

奶牛赛跑

与题见面与问候 差不多

密码锁

$O(n^3)$ 的时间复杂度:只需要枚举每位上1~n之间的数即可,不需要先去枚举答案,降低复杂度。

$O(1)$ 的时间复杂度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<iostream>

using namespace std;

const int N = 110;

int n;
int a[N], b[N];

int both() {
if(n <= 5) return n * n * n;
int res = 1;
for(int i = 0; i < 3; i ++) {
int d = abs(a[i]- b[i]);
res *= max(0, 5 - d) + max(0, 5 - (n - d));
}
return res;
}


int signle() {
if(n < 5) return n * n * n;
return 125;
}

int main() {
cin >> n;
for(int i = 0; i < 3; i ++) cin >> a[i];
for(int i = 0; i < 3; i ++) cin >> b[i];

cout << signle() * 2 - both() << endl;

return 0;
}
记录保存
1
2
3
4
map<vector<string>, int> hash;
vector<string> strs(3);
sort(strs.begin(), strs.end());
hash[strs] ++ ;
滑雪设计

总体上枚举,例如这题枚举区间~

重新排列奶牛

怎么找环,怎么计算环的大小~ 可以用并查集,也可以直接找~