算法
如果两个点从原点开始,都是以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; 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] ++ ;
从总体 上枚举,例如这题枚举区间~
怎么找环,怎么计算环的大小~ 可以用并查集,也可以直接找~