T1 瑞神的序列
题目描述:
瑞神的数学一向是最好的,连强大的咕咕东都要拜倒在瑞神的数学水平之下,虽然咕咕东很苦恼,但是咕咕东拿瑞神一点办法都没有。 5.1期间大家都出去玩了,只有瑞神还在孜孜不倦的学习,瑞神想到了一个序列,这个序列长度为 n,也就是一共有 n个数,瑞神给自己出了一个问题:数列有几段? 段的定义是连续的相同的最长整数序列。
输入描述:
输入第一行一个整数n,表示数的个数。
接下来一行n个空格隔开的整数,表示不同的数字。
输出描述:
输出一行,这个序列有多少段 。
样例输入:
12
2 3 3 6 6 6 1 1 4 5 1 4
1
2
样例输出:
8
思路:创建数组a[n]储存此序列,p储存段数,从序列第二位开始,如果此位置的值不等于上个位置的值,p加一,最后输出p。
#include <iostream>
#include <algorithm>
using namespace std;
int n,a[10000],p;
int main(){
cin>>n;
p=1;
for(int i=1;i<=n;i++){
cin>>a[i];
if(i!=1){
if(a[i]!=a[i-1]) p++;
}
}
cout<<p;
return 0;
}
T2 消消乐大师——Q老师
题目描述:
Q老师是个很老实的老师,最近在积极准备考研。Q老师平时只喜欢用Linux系统,所以Q老师的电 脑上没什么娱乐的游戏,所以Q老师平时除了玩Linux上的赛车游戏SuperTuxKart之外,就是喜欢消消乐了。 游戏在一个包含有 n 行 m 列的棋盘上进行,棋盘的每个格子都有一种颜色的棋子。当一行或一列 上有连续三个或更多的相同颜色的棋子时,这些棋子都被消除。当有多处可以被消除时,这些地方的棋子将同时被消除。 一个棋子可能在某一行和某一列同时被消除。 由于这个游戏是闯关制,而且有时间限制,当Q老师打开下一关时,Q老师的好哥们叫Q老师去爬泰山去了,Q老师不想输在这一关,所以它来求助你了!!
输入描述:
输入第一行包含两个整数n,m,表示行数和列数 ,接下来n行m列,每行中数字用空格隔开,每个数字代表这个位置的棋子的颜色。数字都大于0。
输出描述:
输出n行m列,每行中数字用空格隔开,输出消除之后的棋盘。(如果一个方格中的棋子被消除, 则对应的方格输出0,否则输出棋子的颜色编号。)
样例输入1
4 5
2 2 3 1 2
3 4 5 1 4
2 3 2 1 3
2 2 2 4 4
1
2
3
4
5
样例输出1
2 2 3 0 2
3 4 5 0 4
2 3 2 0 3
0 0 0 4 4
1
2
3
4
样例输入2
4 5
2 2 3 1 2
3 1 1 1 1
2 3 2 1 3
2 2 3 3 3
1
2
3
4
5
样例输出2
2 2 3 0 2
3 0 0 0 0
2 3 2 0 3
2 2 0 0 0
思路:
建立一个set集合,遍历每一个点,检查这个点的x轴和y轴方向,若在某方向上满足消除的条件,则将这个方向上的对应点放入set中。最后遍历set,将对应点的值改为0即可。
改进:建立两个二维数组分别表示某个点的x或y轴方向是否已经检查,若没有则检查,若已经检查则跳过。
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;
struct pos {
int x, y;
bool operator<(const pos& s) const
{
return x != s.x ? x < s.x : y < s.y;
}
};
int n, m, a[35][35];
vector<pos> x;
vector<pos> y;
queue<pos> g;
queue<pos> xx;
queue<pos> yy;
set<pos> c;
void chushi() {
x.clear();
y.clear();
}
void change(int i, int l) {
x.push_back({ i,l });
y.push_back({ i,l });
xx.push({ i,l });
yy.push({ i,l });
while (!xx.empty()) {
pos t = xx.front();
xx.pop();
pos u;
u.y = t.y;
u.x = t.x + 1;
if (u.x <= n && a[u.x][u.y] == a[t.x][t.y]) xx.push(u), x.push_back(u);
}
xx.push({ i,l });
while (!xx.empty()) {
pos t = xx.front();
xx.pop();
pos u;
u.y = t.y;
u.x = t.x - 1;
if (u.x>=1 && a[u.x][u.y] == a[t.x][t.y]) xx.push(u), x.push_back(u);
}
if (x.size() >= 3) {
for (unsigned k = 0; k < x.size(); k++) {
c.insert(x[k]);
}
}
while (!yy.empty()) {
pos t = yy.front();
yy.pop();
pos u;
u.x = t.x;
u.y = t.y + 1;
if (u.y <= m && a[u.x][u.y] == a[t.x][t.y]) yy.push(u), y.push_back(u);
}
yy.push({ i,l });
while (!yy.empty()) {
pos t = yy.front();
yy.pop();
pos u;
u.x = t.x;
u.y = t.y -1;
if (u.y >=1 && a[u.x][u.y] == a[t.x][t.y]) yy.push(u), y.push_back(u);
}
if (y.size() >= 3) {
for (unsigned k = 0; k < y.size(); k++) {
c.insert(y[k]);
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int l = 1; l <= m; l++) {
cin >> a[i][l];
}
}
for (int i = 1; i <= n; i++) {
for (int l = 1; l <= m; l++) {
chushi();
change(i, l);
}
}
for (auto it = c.begin(); it != c.end(); it++) {
a[it->x][it->y] = 0;
}
for (int i = 1; i <= n; i++) {
if (i > 1) cout << endl;
cout<<a[i][1];
for (int l = 2; l <= m; l++) {
cout << " " << a[i][l];
}
}
return 0;
}
T4 咕咕东学英语
题目描述:
咕咕东很聪明,但他最近不幸被来自宇宙的宇宙射线击中,遭到了降智打击,他的英语水平被归 零了!这一切的始作俑者宇宙狗却毫不知情! 此时咕咕东碰到了一个好心人——TT,TT在吸猫之余教咕咕东学英语。今天TT打算教咕咕东字母A 和字母B,TT给了咕咕东一个只有大写A、B组成的序列,让咕咕东分辨这些字母。 但是咕咕东的其他学科水平都还在,敏锐的咕咕东想出一个问题考考TT:咕咕东问TT这个字符串 有多少个子串是Delicious的。 TT虽然会做这个问题,但是他吸完猫发现辉夜大小姐更新了,不想回答这个问题,并抛给了你, 你能帮他解决这个问题吗?
Delicious定义:对于一个字符串,我们认为它是Delicious的当且仅当它的每一个字符都属于一个大于1的回文子串中。
输入描述:
输入第一行一个正整数n,表示字符串长度, 接下来一行,一个长度为n,只由大写字母A、B构成的字符串。
输出描述:
输出仅一行,表示符合题目要求的子串的个数。
样例输入:
5
AABBB
1
2
样例输出:
6
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;
}