A AquaMoon and Two Arrays

题目大意

给两个长度为n的数组,问a数组是否能通过给一个数+1,另一个数-1操作变成数组b,如果能输出操作步数且打印方案

主要思路

如果suma == sumb那么一定能变成,用st数组记录每个ai - bi的值,所有st数组中大于0的值的和就是操作步数,然后再用两个指针一个指向st中的负数,一个指向st中的正数,输出即可

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], b[N];
  19. int st[N];
  20. signed main(void)
  21. {
  22. int T;
  23. cin >> T;
  24. while(T--)
  25. {
  26. cin >> n;
  27. int suma = 0, sumb = 0;
  28. int cnt = 0;
  29. for(int i = 0; i < n; i++) cin >> a[i], suma += a[i];
  30. for(int i = 0; i < n; i++)
  31. {
  32. cin >> b[i];
  33. st[i] = a[i] - b[i];
  34. sumb += b[i];
  35. if(st[i] > 0) cnt += st[i];
  36. }
  37. if(suma != sumb)
  38. {
  39. puts("-1");
  40. }
  41. else
  42. {
  43. int pos1 = -1, pos2 = -1;
  44. for(int i = 0; i < n; i++)
  45. {
  46. if(st[i] < 0 && pos1 == -1) pos1 = i;
  47. if(st[i] > 0 && pos2 == -1) pos2 = i;
  48. if(pos1 != -1 && pos2 != -1)
  49. {
  50. break;
  51. }
  52. }
  53. cout << cnt << endl;
  54. while(pos1 < n || pos2 < n)
  55. {
  56. while(st[pos1] >= 0 && pos1 < n) pos1++;
  57. while(st[pos2] <= 0 && pos2 < n) pos2++;
  58. if(pos1 < n && pos2 < n && st[pos1] < 0 && st[pos2] > 0)
  59. {
  60. cout << pos2 + 1 << ' ' << pos1 + 1 << endl;
  61. st[pos1]++, st[pos2]--;
  62. }
  63. }
  64. }
  65. }
  66. return 0;
  67. }

B AquaMoon and Stolen String

题目大意

给定n个长度为m的字符串,再给n-1个长度为m的字符串,其中n - 1个字符串是由n个字符串中的n-1个交换每个位置上的元素得到,问n个字符串中没有参与交换的是哪个

主要思路

统计每一列中某个字母的个数,如果某一行的所有字母在每一列中都是奇数 那么这一行就是答案

  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 = 100010;
  18. int n, m;
  19. int st[N][30];
  20. string s[N];
  21. signed main(void)
  22. {
  23. int T;
  24. cin >> T;
  25. while(T--)
  26. {
  27. cin >> n >> m;
  28. memset(st, 0, sizeof(st));
  29. for(int i = 0; i < n; i++)
  30. {
  31. cin >> s[i];
  32. for(int j = 0; j < m; j++)
  33. {
  34. st[j][s[i][j] - 'a']++;
  35. }
  36. }
  37. for(int i = 0; i < n - 1; i++)
  38. {
  39. string s;
  40. cin >> s;
  41. for(int j = 0; j < m; j++)
  42. {
  43. st[j][s[j] - 'a']++;
  44. }
  45. }
  46. for(int i = 0; i < n; i++)
  47. {
  48. bool flag = true;
  49. for(int j = 0; j < m; j++)
  50. {
  51. if(st[j][s[i][j] - 'a'] % 2 == 0)
  52. {
  53. flag = false;
  54. break;
  55. }
  56. }
  57. if(flag)
  58. {
  59. cout << s[i] << endl;
  60. break;
  61. }
  62. }
  63. }
  64. return 0;
  65. }

C AquaMoon and Strange Sort

题目大意

给定一个长度为n的数组,刚开始每个元素都指向右,每次交换相邻两个元素都会是元素指向改变,问能否给该数组排序,同时使最后所有元素还是都指向右

主要思路

每个元素都交换两次才能保证最后每个元素还是指向右边,那么开始在奇数位置的元素还在奇数位置,开始在偶数位置的元素还在偶数位置,那么我们把奇数位置元素记下,偶数元素位置元素记下,直接对原数组排序,如果奇数位置还是那些数,则说明能该边,如果奇数位置不是原来那些数,则说明不能改变

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 = 100010;
  18. int n, a[N];
  19. int f[2][N];
  20. signed main(void)
  21. {
  22. int T;
  23. cin >> T;
  24. while(T--)
  25. {
  26. memset(f, 0, sizeof(f));
  27. cin >> n;
  28. for(int i = 0; i < n; i++)
  29. {
  30. cin >> a[i];
  31. f[i % 2][a[i]]++;
  32. }
  33. sort(a, a + n);
  34. for(int i = 0; i < n; i++)
  35. {
  36. f[i % 2][a[i]]--;
  37. }
  38. bool flag = true;
  39. for(int i = 0; i < N; i++)
  40. {
  41. if(f[0][i] || f[1][i])
  42. {
  43. flag = false;
  44. break;
  45. }
  46. }
  47. if(flag) puts("YES");
  48. else puts("NO");
  49. }
  50. return 0;
  51. }

D AquaMoon and Chess

题目大意

给你一个0 1串,1只能隔一个1跳到相邻位置的0(象棋的炮), 问有多少种排列方式

主要思路

1的移动是以11为单位,因此我们可以计算出有多少个11,和计算出有多少个0,相当于n个相同的球放进m个盒子中,且允许空箱,那么答案就为C(n + m - 1, m - 1),m为1可以在0中插入的位置个数,也就是0的个数+1

不同情况组合数公式见:https://blog.csdn.net/u012720552/article/details/80961684

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 = 100010, mod = 998244353;
  18. int n;
  19. int qmi(int a, int k, int p) // 快速幂模板
  20. {
  21. int res = 1 % p;
  22. while (k)
  23. {
  24. if (k & 1) res = res * a % p;
  25. a = a * a % p;
  26. k >>= 1;
  27. }
  28. return res;
  29. }
  30. int C(int a, int b, int p) // 通过定理求组合数C(a, b)
  31. {
  32. if (a < b) return 0;
  33. int x = 1, y = 1; // x是分子,y是分母
  34. for (int i = a, j = 1; j <= b; i --, j ++ )
  35. {
  36. x = x * i % p;
  37. y = y * j % p;
  38. }
  39. return x * qmi(y, p - 2, p) % p;
  40. }
  41. int lucas(int a, int b, int p)
  42. {
  43. if (a < p && b < p) return C(a, b, p);
  44. return (int)C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
  45. }
  46. signed main(void)
  47. {
  48. int T;
  49. cin >> T;
  50. while(T--)
  51. {
  52. cin >> n;
  53. string s;
  54. cin >> s;
  55. int a = 0, b = 0;
  56. for(int i = 0; i < n; i++)
  57. {
  58. if(s[i] == '0') a++;
  59. else
  60. {
  61. int cnt = 0;
  62. while(s[i] == '1')
  63. {
  64. cnt++;
  65. i++;
  66. }
  67. b += cnt / 2;
  68. i--;
  69. }
  70. }
  71. a++;
  72. cout << lucas(a + b - 1, a - 1, mod) << endl;
  73. }
  74. return 0;
  75. }