A Shortest Path with Obstacle

题目大意

给你一个位置A,一个位置B,还有一个不能经过的位置F,让你判断需要多少步能从A到B

主要思路

答案为A到B的曼哈顿距离,仅当ABF在一条直线上且F在AB中间时答案+2

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. const int N = 200010;
  18. int n, a[N];
  19. signed main(void)
  20. {
  21. int T;
  22. cin >> T;
  23. while(T--)
  24. {
  25. int x, y, x1, y1, x2, y2;
  26. cin >> x >> y >> x1 >> y1 >> x2 >> y2;
  27. if(x == x1 && x1 == x2 && (y < y2 && y2 < y1 || y > y2 && y2 > y1) || y == y1 && y1 == y2 && (x < x2 && x2 < x1 || x > x2 && x2 > x1))
  28. {
  29. cout << abs(x - x1) + abs(y - y1) + 2 << endl;
  30. }
  31. else
  32. {
  33. cout << abs(x - x1) + abs(y - y1) << endl;
  34. }
  35. }
  36. return 0;
  37. }

B Alphabetical Strings

题目大意

从a到z添加字母,每次只能添加在字符串的最左边或者最右边,给定一个字符串,问该字符串是不是由此操作得到的

主要思路

从a开始,用两个指针来往左或往右判断即可

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. const int N = 200010;
  18. int n, a[N];
  19. signed main(void)
  20. {
  21. int T;
  22. cin >> T;
  23. while(T--)
  24. {
  25. string t;
  26. cin >> t;
  27. int l, r;
  28. bool flag1 = false;
  29. for(int i = 0; i < t.size(); i++)
  30. {
  31. if(t[i] == 'a') l = r = i, flag1 = true;
  32. }
  33. bool flag = true;
  34. char c = 'b';
  35. while(true)
  36. {
  37. if(l > 0 && t[l - 1] == c)
  38. {
  39. l--;
  40. c++;
  41. }
  42. else if(r < t.size() - 1 && t[r + 1] == c)
  43. {
  44. r++;
  45. c++;
  46. }
  47. else
  48. {
  49. if(l != 0 || r != t.size() - 1) flag = false;
  50. break;
  51. }
  52. }
  53. if(flag && flag1) puts("YES");
  54. else puts("NO");
  55. }
  56. return 0;
  57. }

C Pair Programming

题目大意

刚开始给你一个大小K,然后给a,b两个数组,问你能否在不改变a,b数组本身顺序的情况下,合并a,b数组,且合并后的数组要满足,当数组元素为0时k+1,当不为0时该元素值>=k

主要思路

贪心+双指针,a,b两个数组分别一个指针,当有0时继续遍历,直到a,b都不为0时判断能否将两个元素放入合并后的数组

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. const int N = 310;
  18. int a[N], b[N];
  19. int cnt, ans[N];
  20. signed main(void)
  21. {
  22. int T;
  23. cin >> T;
  24. while(T--)
  25. {
  26. cnt = 0;
  27. int k, n, m;
  28. cin >> k >> n >> m;
  29. for(int i = 0; i < n; i++) cin >> a[i];
  30. for(int i = 0; i < m; i++) cin >> b[i];
  31. int ta = 0, tb = 0;
  32. int t = k;
  33. bool flag = true;
  34. while(cnt < n + m && flag)
  35. {
  36. if(a[ta] == 0 && ta < n) ans[cnt++] = a[ta], ta++, t++;
  37. else if(b[tb] == 0 && tb < m) ans[cnt++] = b[tb], tb++, t++;
  38. else
  39. {
  40. if(a[ta] <= t && ta < n) ans[cnt++] = a[ta], ta++;
  41. else if(b[tb] <= t && tb < m) ans[cnt++] = b[tb], tb++;
  42. else if(a[ta] > t && ta < n && b[tb] > t && tb < m ||
  43. (ta >= n && b[tb] > t && tb < m) ||
  44. (a[ta] > t && ta < n && tb >= m)) flag = false;
  45. }
  46. }
  47. if(flag)
  48. {
  49. for(int i = 0; i < n + m; i++)
  50. {
  51. cout << ans[i] << ' ';
  52. }
  53. cout << endl;
  54. }
  55. else cout << -1 << endl;
  56. }
  57. return 0;
  58. }

D Co-growing Sequence

题目大意

给一个数组x,想让你求一个字典序最小数组y,使x的每个元素与y异或后的数组k,满足ki & ki+1 = ki

主要思路

  • 当(x[i] & (x[i - 1] ^ y[i - 1])) == (x[i - 1] ^ y[i - 1])满足时y[i] = 0
  • 否则,设t = x[i - 1] ^ y[i - 1],(x ^ y) & t = t 说明t二进制表示中为1的位,(x ^ y)也一定为1,想求y最小本质上是找t中二进制位为1而x中二进制位为0的位,y中的这一位一定为1且仅这些位为1,那么y最小

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. const int N = 200010;
  18. int n, x[N], y[N];
  19. int t[N];
  20. signed main(void)
  21. {
  22. int T;
  23. cin >> T;
  24. while(T--)
  25. {
  26. cin >> n;
  27. for(int i = 0; i < n; i++) cin >> x[i];
  28. y[0] = 0;
  29. for(int i = 1; i < n; i++)
  30. {
  31. if((x[i] & (x[i - 1] ^ y[i - 1])) == (x[i - 1] ^ y[i - 1])) y[i] = 0;
  32. else
  33. {
  34. int t = x[i - 1] ^ y[i - 1];
  35. y[i] = (x[i] ^ t) & t;
  36. }
  37. }
  38. for(int i = 0; i < n; i++) cout << y[i] << ' ';
  39. cout << endl;
  40. }
  41. return 0;
  42. }

E Air Conditioners

题目大意

给一个n和k,位置为1~n,接下来给一个长度为k的数组表示空调的位置,再给一个长度为k的数组表示该位置空调的温度,距离空调位置为1那么温度+1,问每个位置的最低温度

主要思路

我们先从左往右扫描一遍空调对右边元素的影响,再从右往左扫描一遍空调对左边元素影响即可

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. const int N = 300010;
  18. int st[N], a[N];
  19. int n, k;
  20. signed main(void)
  21. {
  22. int T;
  23. cin >> T;
  24. while(T--)
  25. {
  26. memset(a, 0x3f, sizeof(a));
  27. cin >> n >> k;
  28. for(int i = 0; i < k; i++) cin >> st[i];
  29. for(int i = 0; i < k; i++)
  30. {
  31. cin >> a[st[i]];
  32. }
  33. for(int i = 2; i <= n; i++) a[i] = min(a[i], a[i - 1] + 1);
  34. for(int i = n - 1; i >= 1; i--) a[i] = min(a[i], a[i + 1] + 1);
  35. for(int i = 1; i <= n; i++) cout << a[i] << ' ';
  36. puts("");
  37. }
  38. return 0;
  39. }

F Array Stabilization (GCD version)

题目大意

给定一个长度为n的环,我们对数组每次操作都能使ai = gcd(a[i], a[i + 1]),问至少进行多少次操作使数组所有值相等

主要思路

将长度为n的环展开为2*n的数组,也就是将两个长度为n的数组拼起来,便于操作(环常用操作)。

gcd(gcd(a, b), gcd(b, c)) == gcd(gcd(a, b), c)

如果有两个相邻的数x[i], x[i+1]不等, 由于这个公式,那我们每次都往后取gcd直到两个数相同为止,记下每次操作的最大次数,最后取一个max即可。

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. const int N = 200010;
  18. int n, a[2 * N];
  19. int gcd(int a, int b)
  20. {
  21. return b ? gcd(b, a % b) : a;
  22. }
  23. signed main(void)
  24. {
  25. int T;
  26. cin >> T;
  27. while(T--)
  28. {
  29. cin >> n;
  30. for(int i = 0; i < n; i++)
  31. {
  32. cin >> a[i];
  33. a[i + n] = a[i];
  34. }
  35. int ans = 0;
  36. for(int i = 0; i < n; i++)
  37. {
  38. int cnt = 0;
  39. int x = a[i];
  40. int y = a[i + 1];
  41. int t = i + 1;
  42. while(x != y)
  43. {
  44. x = gcd(x, a[t]);
  45. y = gcd(y, a[t + 1]);
  46. t++;
  47. cnt++;
  48. }
  49. ans = max(ans, cnt);
  50. }
  51. cout << ans << endl;
  52. }
  53. return 0;
  54. }