csp模测 - week12

题一:瑞神的序列

题意:
在这里插入图片描述
思路:
需要求出数列有几段,只需要遍历数列,每次判断与前一个数是否相同,若是不同则给 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值