Contest Info
Solved | A | B | C | D | E | F | G | H | I | J | K |
---|---|---|---|---|---|---|---|---|---|---|---|
4/11 | Ø | O | O | O |
- O 在比赛中通过(O为自己,O为队友)
- Ø 赛后通过
- ! 尝试了但是失败了
- 空白 表示没有尝试
Solutions
A. All-one Matrices
B. Beauty Values
C. CDMA(构造)
题意:构造由-1,1组成的m*m矩阵,使得任意两个不同(这里指的是数字有不同的地方)的行对应位置乘积和为0
思路:首先 m=2 时的答案是已经知道了的,考虑用 m 构造出 2m 的解:
不妨设方阵 A 为 m 的解,那么下面这个方阵则是 2m 的一个解:
[A A]
[A -A]
通过这种方法去构造我们就能得到正解
那会学姐直接搜百度百科搜CDMA,找了一会就发现这个和Walsh函数的生成方式差不多的,题目中只是把Walsh函数的0看作-1,1看作+1,如下:
Code(比赛的时候直接打表交了)
#include <cstdio> #include <algorithm> using namespace std; const int maxn = 2000; int h[maxn][maxn]; int main() { int g; scanf("%d", &g); h[1][1] = 1; int cnt = 1; for (int i = 1; i <= 10; i++) { for (int k = 1; k <= cnt; k++) { for (int j = 1; j <= cnt; j++) { h[k][cnt+j] = h[k][j]; h[k+cnt][j] = h[k][j]; h[k+cnt][cnt+j] = -h[k][j]; } } cnt = cnt<<1; } for (int i = 1; i <= g; i++) { for (int j = 1; j <= g; j++) { printf("%d ", h[i][j]); } if(i!=g) printf("\n"); } }
G. Gemstones
题意:
思路:栈的应用
从左到右依次把字符加入栈中,如果某个时刻栈顶的三个字符相同,则将其弹出栈顶并把答案加 1,最后输 出一下答案即可
开始的时候我是想把重复字符串的个数保存起来,当个数为3的时候就弹栈,但没考虑到三个相同元素必须相连才能弹栈,最后想说的是,很多时候用数组去模拟栈加个top标识反而比调用stack要好用些,写起来也方便
Code
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1e5+5; int ans, flag; int a[maxn]; char str[maxn], s[maxn]; int main() { scanf("%s", &str); int top = 0; for (int i = 0; i < strlen(str); i++) { s[++top] = str[i]; if (i>1) flag = s[top]==s[top-1]&&s[top-1]==s[top-2]?1:0; if (flag) top -= 3, ans++; } printf("%d", ans); }
其实可以写的更简洁一点,都不需要开两个数组,把str每个元素扫描完后对应的那个位置就没有用,因此可以反复利用,最后判断下条件就可以了,只不过那样写会稍微难懂那么一点点