题一:瑞神的序列
题意:
思路:
需要求出数列有几段,只需要遍历数列,每次判断与前一个数是否相同,若是不同则给 ans 加上1,遍历完成后得到的ans就是答案,输出即可。
代码:
#include <iostream>
using namespace std;
int n;
int a[1010];
int main(){
cin >> n;
for (int i = 0; i < n; i++){
cin >> a[i];
}
int ans = 1;
for (int i = 1; i < n; i++){
if(a[i] != a[i - 1]){
ans++;
}
}
cout << ans << endl;
}
题二:消消乐大师 - Q老师
题意:
思路:
该题在输入数据后,先判断每一行是否有可以消除部分,判断任意一行时,先定义两个int型变量 l 和 r,用来维护左右两端,进入一个循环,将r自加1,若是左右两端的数据值不同,则再判断若是左右两端相距超过3,则消除这一部分,由于判断行之后还要判断列,所以构造了另一个二维数组,用来记录当前位置是否被消除。
判断每一行之后,再用同样的方式判断每一列,然后根据记录是否消除的二维数组把矩阵的数据更新,然后进行输出。
代码:
//n行m列
//一行或一列有连续大于等于 3 个相同颜色,棋子消除
//多处同时可消除,就同时消除
//
#include <iostream>
using namespace std;
int n, //行数
m; //列数
int board[35][35];
int ans[35][35] = { -1 };
int main(){
cin >> n >> m;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
cin >> board[i][j];
ans[i][j] = -1;
}
}//输入完成
//接下来先判断每一行
for (int i = 1; i <= n; i++){
int l = 1, r = 1;
while (r < m){
r++;
//若是 r 和 l 的值不再一样了
if (board[i][l] != board[i][r]){
//1、r-l>=3,可以消掉
if (r - l >= 3){
for (int j = l; j < r; j++){
ans[i][j] = 0;
}
l = r;
}
//2、r-l<3
else {
l = r;
}
}
// r 和 l 的值还是一样的
else {
}
if (r == m && r - l + 1 >= 3){
for (int j = l; j <= r; j++){
ans[i][j] = 0;
}
}
}
}
//接下来先判断每一列
for (int j = 1; j <= m; j++){
int l = 1, r = 1;
while (r < n){
r++;
//若是 r 和 l 的值不再一样了
if (board[l][j] != board[r][j]){
//1、r-l>=3,可以消掉
if (r - l >= 3){
for (int i = l; i < r; i++){
ans[i][j] = 0;
}
l = r;
}
//2、r-l<3
else {
l = r;
}
}
// r 和 l 的值还是一样的
else {
}
if (r == m && r - l + 1 >= 3){
for (int i = l; i <= r; i++){
ans[i][j] = 0;
}
}
}
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
if (ans[i][j] == -1){
ans[i][j] = board[i][j];
}
}
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
cout << ans[i][j];
if(j < m){
cout << " ";
}
}
if(i < n)
cout << endl;
}
}
题三:咕咕咚学英语
题意:
思路:
要判断属于delicious的子串很复杂,但是要判断不是delicious的子串较为容易,以下四种情况都不是delicious子串:
- AB…B
- A…AB
- BA…A
- B…BA
对于AB…B(t个B),共有t个不是delicious的子串。
故可以把字符串分为不同的段,对于相邻的两个段,如A…AB…B(其中m个A,n个B),其中共有m+n-1个非delicious的子串;对于相邻三个段,如A…AB…BA…A(其中l个A,m个B,n个A),其中有l+2m+n-2个非delicious的子串。以此类推,可以找出第一个字符变化的位置x以及最后一次字符变化的位置y,非delicious子串数即为2(y-x) + n-y+x,再用一共的子串数量C(n,2)减去非delicious子串数量即可得到答案。
代码:
#include <iostream>
using namespace std;
int main(){
long long n;
cin >> n;
char s[300005];
cin >> s;
long long ans = (long long)(n*(n-1)/2);
long long l = -1;
long long r = -1;
long long nm = 0;//段数 -1
for (int i = 0; i < n - 1; i++) {
if (s[i] != s[i + 1]) {
nm++;
if (l == -1) {
l = i;
}
r = i;
}
}
if (l==-1) {
cout << ans << endl;
}
else
cout << ans - 2*(r - l) - n + r - l + nm << endl;
}