T1 瑞神的序列
瑞神的数学一向是最好的,连强大的咕咕东都要拜倒在瑞神的数学水平之下,虽然咕咕东很苦恼,但是咕咕东拿瑞神一点办法都没有。
5.1期间大家都出去玩了,只有瑞神还在孜孜不倦的学习,瑞神想到了一个序列,这个序列长度为n,也就是一共有n个数,瑞神给自己出了一个问题:数列有几段?
段的定义是连续的相同的最长整数序列
解题思路
从第二个数开始与前面的一个属比较,若不同则结果ans+1,ans初始值为1.
#include<iostream>
using namespace std;
int a[1010];
int main()
{
int n;
cin >> n;
cin >> a[0];
int ans = 1;
for (int i = 1; i < n; i++)
{
cin >> a[i];
if (a[i] != a[i - 1])
ans++;
}
cout << ans;
}
T2 消消乐大师——Q老师
Q老师是个很老实的老师,最近在积极准备考研。Q老师平时只喜欢用Linux系统,所以Q老师的电脑上没什么娱乐的游戏,所以Q老师平时除了玩Linux上的赛车游戏SuperTuxKart之外,就是喜欢消消乐了。
游戏在一个包含有n 行m 列的棋盘上进行,棋盘的每个格子都有一种颜色的棋子。当一行或一列上有连续三个或更多的相同颜色的棋子时,这些棋子都被消除。当有多处可以被消除时,这些地方的棋子将同时被消除。
一个棋子可能在某一行和某一列同时被消除。
由于这个游戏是闯关制,而且有时间限制,当Q老师打开下一关时,Q老师的好哥们叫Q老师去爬泰山去了,Q老师不想输在这一关,所以它来求助你了!!
解题思路
使用二维数组a记录每个位置的颜色
使用二维数组b记录每个位置是否可以消除,0代表可以消除
先一行行的遍历a,看每个位置的前一个位置和后一个位置是否与其颜色相同,若相同则可以消除,将数组b的值改成0,再一列列遍历即可
#include<iostream>
using namespace std;
int a[40][40], b[40][40];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
b[i][j] = a[i][j];
}
}
for (int j = 1; j <= m; j++)
{
for (int i = 1; i <= n; i++)
{
if (a[i][j] == a[i - 1][j] && a[i][j] == a[i + 1][j])
b[i][j] = b[i - 1][j] = b[i + 1][j] = 0;
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (a[i][j] == a[i][j - 1] && a[i][j] == a[i][j + 1])
b[i][j] = b[i][j - 1] = b[i][j + 1] = 0;
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (j != 1)
cout << " ";
cout << b[i][j];
}
cout << endl;
}
return 0;
T4 咕咕东学英语
题意
咕咕东很聪明,但他最近不幸被来自宇宙的宇宙射线击中,遭到了降智打击,他的英语水平被归零了!这一切的始作俑者宇宙狗却毫不知情!
此时咕咕东碰到了一个好心人——TT,TT在吸猫之余教咕咕东学英语。今天TT打算教咕咕东字母A和字母B,TT给了咕咕东一个只有大写A、B组成的序列,让咕咕东分辨这些字母。
但是咕咕东的其他学科水平都还在,敏锐的咕咕东想出一个问题考考TT:咕咕东问TT这个字符串有多少个子串是Delicious的。
TT虽然会做这个问题,但是他吸完猫发现辉夜大小姐更新了,不想回答这个问题,并抛给了你,你能帮他解决这个问题吗?
Delicious定义:对于一个字符串,我们认为它是Delicious的当且仅当它的每一个字符都属于一个大于1的回文子串中。
解题思路
对于该样例,符合条件的六个子串分别是:
s1-s4 AABB
s1-s5 AABBB
s3-s4 BB
s3-s5 BBB
s4-s5 BB
思路:首先确定对于长度为n的字符串一共有(n-1)*n/2中可能,当减去所有不满足条件的情况即为答案。
经过观察可知,不满足Delicious定义的字符串为…AB…或者…BA…这样的字符串,对于[n]AB这样的字符串,一共有n种不满足条件的子串.为AB,AAB,…,[n]AB,若最左边的A之前还有B,则形成BA[n],又有n个不满足条件的子串,说明此时一段要计算两次,而左右两端只用计算一次。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int ma=3E5+10;
string s;
long long a[ma],len,num;
int main(){
cin>>len;
cin>>s;
fill(a,a+ma,0);
long long p=0;
a[0]=1;
num=len*(len-1)/2;
for(unsigned i=1;i<s.size();i++){
if(s[i]==s[i-1]) a[p]++;
else {
p++;
a[p]++;
}
}
if(p==0){
cout<<num;
return 0;
}
num-=a[0];
for(int i=1;i<p;i++) num-=2*a[i];
num-=a[p];
num+=p;
cout<<num;
return 0;