A AquaMoon and Two Arrays
题目大意
给两个长度为n的数组,问a数组是否能通过给一个数+1,另一个数-1操作变成数组b,如果能输出操作步数且打印方案
主要思路
如果suma == sumb那么一定能变成,用st数组记录每个ai - bi的值,所有st数组中大于0的值的和就是操作步数,然后再用两个指针一个指向st中的负数,一个指向st中的正数,输出即可
AC代码
#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <string>#include <cmath>#include <unordered_map>#include <queue>#include <map>using namespace std;#define int long long#define debug(a) cout << #a << " = " << a << endl;#define x first#define y secondtypedef pair<int, int> P;const int N = 200010;int n, a[N], b[N];int st[N];signed main(void){int T;cin >> T;while(T--){cin >> n;int suma = 0, sumb = 0;int cnt = 0;for(int i = 0; i < n; i++) cin >> a[i], suma += a[i];for(int i = 0; i < n; i++){cin >> b[i];st[i] = a[i] - b[i];sumb += b[i];if(st[i] > 0) cnt += st[i];}if(suma != sumb){puts("-1");}else{int pos1 = -1, pos2 = -1;for(int i = 0; i < n; i++){if(st[i] < 0 && pos1 == -1) pos1 = i;if(st[i] > 0 && pos2 == -1) pos2 = i;if(pos1 != -1 && pos2 != -1){break;}}cout << cnt << endl;while(pos1 < n || pos2 < n){while(st[pos1] >= 0 && pos1 < n) pos1++;while(st[pos2] <= 0 && pos2 < n) pos2++;if(pos1 < n && pos2 < n && st[pos1] < 0 && st[pos2] > 0){cout << pos2 + 1 << ' ' << pos1 + 1 << endl;st[pos1]++, st[pos2]--;}}}}return 0;}
B AquaMoon and Stolen String
题目大意
给定n个长度为m的字符串,再给n-1个长度为m的字符串,其中n - 1个字符串是由n个字符串中的n-1个交换每个位置上的元素得到,问n个字符串中没有参与交换的是哪个
主要思路
统计每一列中某个字母的个数,如果某一行的所有字母在每一列中都是奇数 那么这一行就是答案
#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <string>#include <cmath>#include <unordered_map>#include <queue>#include <map>using namespace std;#define int long long#define debug(a) cout << #a << " = " << a << endl;#define x first#define y secondtypedef pair<int, int> P;const int N = 100010;int n, m;int st[N][30];string s[N];signed main(void){int T;cin >> T;while(T--){cin >> n >> m;memset(st, 0, sizeof(st));for(int i = 0; i < n; i++){cin >> s[i];for(int j = 0; j < m; j++){st[j][s[i][j] - 'a']++;}}for(int i = 0; i < n - 1; i++){string s;cin >> s;for(int j = 0; j < m; j++){st[j][s[j] - 'a']++;}}for(int i = 0; i < n; i++){bool flag = true;for(int j = 0; j < m; j++){if(st[j][s[i][j] - 'a'] % 2 == 0){flag = false;break;}}if(flag){cout << s[i] << endl;break;}}}return 0;}
C AquaMoon and Strange Sort
题目大意
给定一个长度为n的数组,刚开始每个元素都指向右,每次交换相邻两个元素都会是元素指向改变,问能否给该数组排序,同时使最后所有元素还是都指向右
主要思路
每个元素都交换两次才能保证最后每个元素还是指向右边,那么开始在奇数位置的元素还在奇数位置,开始在偶数位置的元素还在偶数位置,那么我们把奇数位置元素记下,偶数元素位置元素记下,直接对原数组排序,如果奇数位置还是那些数,则说明能该边,如果奇数位置不是原来那些数,则说明不能改变
AC代码
#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <string>#include <cmath>#include <unordered_map>#include <queue>#include <map>using namespace std;#define int long long#define debug(a) cout << #a << " = " << a << endl;#define x first#define y secondtypedef pair<int, int> P;const int N = 100010;int n, a[N];int f[2][N];signed main(void){int T;cin >> T;while(T--){memset(f, 0, sizeof(f));cin >> n;for(int i = 0; i < n; i++){cin >> a[i];f[i % 2][a[i]]++;}sort(a, a + n);for(int i = 0; i < n; i++){f[i % 2][a[i]]--;}bool flag = true;for(int i = 0; i < N; i++){if(f[0][i] || f[1][i]){flag = false;break;}}if(flag) puts("YES");else puts("NO");}return 0;}
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代码
#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <string>#include <cmath>#include <unordered_map>#include <queue>#include <map>using namespace std;#define int long long#define debug(a) cout << #a << " = " << a << endl;#define x first#define y secondtypedef pair<int, int> P;const int N = 100010, mod = 998244353;int n;int qmi(int a, int k, int p) // 快速幂模板{int res = 1 % p;while (k){if (k & 1) res = res * a % p;a = a * a % p;k >>= 1;}return res;}int C(int a, int b, int p) // 通过定理求组合数C(a, b){if (a < b) return 0;int x = 1, y = 1; // x是分子,y是分母for (int i = a, j = 1; j <= b; i --, j ++ ){x = x * i % p;y = y * j % p;}return x * qmi(y, p - 2, p) % p;}int lucas(int a, int b, int p){if (a < p && b < p) return C(a, b, p);return (int)C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;}signed main(void){int T;cin >> T;while(T--){cin >> n;string s;cin >> s;int a = 0, b = 0;for(int i = 0; i < n; i++){if(s[i] == '0') a++;else{int cnt = 0;while(s[i] == '1'){cnt++;i++;}b += cnt / 2;i--;}}a++;cout << lucas(a + b - 1, a - 1, mod) << endl;}return 0;}
