[关闭]
@Dmaxiya 2018-08-17T10:20:33.000000Z 字数 3790 阅读 1068

Codeforces Round #447 (Div. 2)

Codeforces


Contests 链接:Codeforces Round #447 (Div. 2)
过题数:2
排名:995/11398

A. QAQ

题意

给定一个字符串 ,询问这个字符串中有多少个字符子序列是 "QAQ"。

输入

输入只包含一个字符串 ,且字符串中只含有大写字母。

输出

输出 "QAQ" 子序列的个数。

样例

输入 输出 提示
QAQAQYSYIOIWIN 4 四个子 "QAQ" 串分别为:



QAQQQZZYNOIWIN 4

题解

对于每一个字符 'A',能够形成的 "QAQ" 子序列的个数,等于 'A' 左边的 'Q' 字符的数量乘上右边的 'Q' 字符的数量,'Q' 字符的数量可以预处理。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 100 + 100;
  19. int ans;
  20. char str[maxn];
  21. int Left[maxn], Right[maxn];
  22. int main() {
  23. #ifdef Dmaxiya
  24. freopen("test.txt", "r", stdin);
  25. #endif // Dmaxiya
  26. ios::sync_with_stdio(false);
  27. while(scanf("%s", str + 1) != EOF) {
  28. ans = 0;
  29. int len = strlen(str + 1);
  30. Left[0] = Right[len + 1] = 0;
  31. for(int i = 1; i <= len; ++i) {
  32. Left[i] = Left[i - 1];
  33. if(str[i] == 'Q') {
  34. ++Left[i];
  35. }
  36. }
  37. for(int i = len; i >= 1; --i) {
  38. Right[i] = Right[i + 1];
  39. if(str[i] == 'Q') {
  40. ++Right[i];
  41. }
  42. }
  43. for(int i = 1; i <= len; ++i) {
  44. if(str[i] == 'A') {
  45. ans += Left[i] * Right[i];
  46. }
  47. }
  48. printf("%d\n", ans);
  49. }
  50. return 0;
  51. }

B. Ralph And His Magic Field

题意

在一个 的网格中填上整数,要求每一行和每一列的整数的乘积都等于 ,问有多少种填数的方案。

输入

输入只包含三个整数

输出

输出总的方案数对 取模后的结果。

样例

输入 输出 提示
1 1 -1 1 只能将 填入唯一的格子中。
1 3 1 1 三格都只能填
3 3 -1 16

题解

只等于 可以知道,填入的整数只能是 或者 ,其次,不论前面的填入的乘积是多少,最后一行或者一列的数字总能填上一个 或者 来得到 ,因此 列的方格可以填 的任意一种组合方式,总的方案数为 ,考虑最后一个方格 填入的数字的情况,这个位置填入的数字由第 行的前 个数字和第 列的前 行数字同时决定,当 时没有任何问题,当 ,必须保证 ,否则这个位置不论填什么数字都无法满足条件。最后由于 都很大,如果直接相乘会爆 long long,所以要用个欧拉降幂公式

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const LL MOD = 1000000007;
  19. const LL phi = MOD - 1;
  20. LL n, m, k, p;
  21. LL fast_pow(LL res, LL n) {
  22. LL ans;
  23. for(ans = 1; n != 0; n >>= 1) {
  24. if((n & 1) == 1) {
  25. ans = (ans * res) % MOD;
  26. }
  27. res = (res * res) % MOD;
  28. }
  29. return ans;
  30. }
  31. int main() {
  32. #ifdef Dmaxiya
  33. freopen("test.txt", "r", stdin);
  34. #endif // Dmaxiya
  35. ios::sync_with_stdio(false);
  36. while(scanf("%I64d%I64d%I64d", &n, &m, &k) != EOF) {
  37. if(k == -1 && n % 2 != m % 2) {
  38. printf("0\n");
  39. continue;
  40. }
  41. if(n >= phi || m >= phi || n * m >= phi) {
  42. p = ((n - 1) % phi) * ((m - 1) % phi) % phi + phi;
  43. } else {
  44. p = (n - 1) * (m - 1);
  45. }
  46. printf("%I64d\n", fast_pow(2, p));
  47. }
  48. return 0;
  49. }

C. Marco and GCD Sequence

题意

对于任意一个长度为 的整数序列,将这个序列的任意一个区间 放入一个集合 中,在这个集合中,如果有两个相同的区间 的值,在集合中也只保留一个,现在给定集合 ,要求构造出一个满足条件的序列。

输入

第一行为一个整数 ,表示集合的大小,第二行为 个整数 ,给出的数字一定是按升序排列的。

输出

如果可以构造出这样的序列,就输出这个序列,第一行为一个整数 ,第二行为 个整数 ,如果有多解输出任意一个,否则输出 。数据保证如果存在解,解的序列个数一定有不超过 的,且 一定可以不超过 .

样例

输入 输出
4
2 4 6 12
3
4 6 12
2
2 3
-1

题解

首先判断给出的所有数字的最大公约数是否等于最小的数字,如果不等于,则输出 ,否则将原序列的所有数字输出,并且隔一个插入一个最小的数字,就能满足任意一个长度大于 的区间的 都等于最小的数字。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 1000000 + 100;
  19. int n, cnt;
  20. int ans[maxn], num[maxn];
  21. int gcd(int x, int y) {
  22. return (y == 0? x: gcd(y, x % y));
  23. }
  24. int main() {
  25. #ifdef Dmaxiya
  26. freopen("test.txt", "r", stdin);
  27. #endif // Dmaxiya
  28. ios::sync_with_stdio(false);
  29. while(scanf("%d", &n) != EOF) {
  30. cnt = 0;
  31. for(int i = 1; i <= n; ++i) {
  32. scanf("%d", &num[i]);
  33. }
  34. int Gcd = num[1];
  35. for(int i = 2; i <= n; ++i) {
  36. Gcd = gcd(Gcd, num[i]);
  37. }
  38. if(Gcd != num[1]) {
  39. printf("-1\n");
  40. continue;
  41. }
  42. for(int i = 1; i <= n; ++i) {
  43. ans[cnt++] = num[i];
  44. ans[cnt++] = num[1];
  45. }
  46. printf("%d\n", cnt);
  47. for(int i = 0; i < cnt; ++i) {
  48. if(i != 0) {
  49. printf(" ");
  50. }
  51. printf("%d", ans[i]);
  52. }
  53. printf("\n");
  54. }
  55. return 0;
  56. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注