文章目录
T1 瑞神的序列
题目描述
瑞神的数学一向是最好的,连强大的咕咕东都要拜倒在瑞神的数学水平之下,虽然咕咕东很苦 恼,但是咕咕东拿瑞神一点办法都没有。 5.1期间大家都出去玩了,只有瑞神还在孜孜不倦的学习,瑞神想到了一个序列,这个序列长度为 ,也就是一共有 个数,瑞神给自己出了一个问题:数列有几段? 段的定义是连续的相同的最长整数序列。
输入描述
输入第一行一个整数n,表示数的个数 接下来一行n个空格隔开的整数,表示不同的数字。
输出描述
输出一行,这个序列有多少段。
数据规模
数据点 | 数据范围 |
---|---|
<=1000 | <=1000 |
思路
遍历序列,利用一个变量t记录当前段的数值,如果遍历到的数a[i]与t不同,那么段数加1,t=a[i]。
需注意的点
最开始t应该初始化为一个序列中不可能出现的数。
完整代码
#include<iostream>
using namespace std;
int n;
int a[5000];
int t=1005;
int cnt;
int main ()
{
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++)
{
if(a[i] != t)
{
cnt++;
t=a[i];
}
}
cout<<cnt<<endl;
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,否则输出棋子的颜色编号。
数据规模
n | m | 颜色数字大小 |
---|---|---|
<=30 | <=30 | <10 |
基本思路
本题的数据规模并不大,把棋盘存储在n x m二维数组a中,遍历一遍数组,找到所有会变为0的点,并将结果存在n x m的二维数组t中,然后输出按顺序t的元素即可。
对于二维数组中元素a[i][j],满足下列情况之一就应该变为0。
- a[i-2][j],a[i-1][j]均合法,且a[i-2][j] = a[i-1][j] = a[i][j];
- a[i-1][j],a[i+1][j]均合法,且a[i-1][j] = a[i][j] = a[i+1][j];
- a[i+1][j],a[i+2][j]均合法,且a[i][j] = a[i+1][j] = a[i+2][j];
- a[i][j-1],a[i][j-2]均合法,且a[i][j-2] = a[i][j-1] = a[i][j];
- a[i][j-1],a[i][j+1]均合法,且a[i][j-1] = a[i][j] = a[i][j+1];
- a[i][j+1],a[i][j+2]均合法,且a[i][j] = a[i][j+1] = a[i][j+2];
完整代码
#include<iostream>
using namespace std;
int n, m;
int a[50][50];
int t[50][50];
bool isvld(int i, int j)
{
return (i>=1 && i<=n && j>=1 && j<=m);
}
bool can_clr(int i1, int j1, int i2, int j2, int i3, int j3)
{
if(isvld(i1, j1) && isvld(i2, j2) && isvld(i3, j3))
{
if(a[i1][j1] == a[i2][j2] && a[i2][j2] == a[i3][j3]) return true;
}
return false;
}
int main ()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(can_clr(i,j,i,j-1,i,j-2) ||
can_clr(i,j,i,j-1,i,j+1) ||
can_clr(i,j,i,j+1,i,j+2) ||
can_clr(i,j,i-1,j,i-2,j) ||
can_clr(i,j,i-1,j,i+1,j) ||
can_clr(i,j,i+1,j,i+2,j))
t[i][j] = 0;
else t[i][j] = a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<m;j++)
{
cout<<t[i][j]<<" ";
}
cout<<t[i][m]<<endl;
}
return 0;
}
T4 咕咕东学英语
题目描述
咕咕东很聪明,但他最近不幸被来自宇宙的宇宙射线击中,遭到了降智打击,他的英语水平被归 零了!这一切的始作俑者宇宙狗却毫不知情! 此时咕咕东碰到了一个好心人——TT,TT在吸猫之余教咕咕东学英语。今天TT打算教咕咕东字母A 和字母B,TT给了咕咕东一个只有大写A、B组成的序列,让咕咕东分辨这些字母。 但是咕咕东的其他学科水平都还在,敏锐的咕咕东想出一个问题考考TT:咕咕东问TT这个字符串 有多少个子串是Delicious的。 TT虽然会做这个问题,但是他吸完猫发现辉夜大小姐更新了,不想回答这个问题,并抛给了你, 你能帮他解决这个问题吗? Delicious定义:对于一个字符串,我们认为它是Delicious的当且仅当它的每一个字符都属于一个 大于1的回文子串中。
输入描述
输入第一行一个正整数n,表示字符串长度 接下来一行,一个长度为n只由大写字母A、B构成的字符串。
输出描述
输出仅一行,表示符合题目要求的子串的个数。
数据规模
n < = 3 × 1 0 5 n<=3\times10^5 n<=3×105
基本思路
题目中一个非常非常重要的条件是:字符串中只含有A,B两个字母。正是因为这个原因,只有AB,ABB,ABBB,… 和 BA,BAA,BAAA,…以及这些字符串的逆序列是不符合题目要求的字符串。
我们可以知道,子串的总数是 n ( n − 1 ) / 2 n(n-1)/2 n(n−1)/2,只需统计不合法的字符串,用总数减去即可。
需要注意的点
- 统计不合法的子串可以通过正反两次遍历得到,但是要注意的是,这样做"AB","BA"两个字符串被多统计了一次。
- 计算 n ( n − 1 ) / 2 n(n-1)/2 n(n−1)/2时要小心整形溢出。
完整代码
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int n;
string s;
char c;
int cnt;
char tmp(char c)
{
return (('B' - c) + 'A');
}
void add()
{
c=s[0];
for(int i=1;i<n;i++)
{
if(s[i] != c) cnt += 1;
else if(s[i-1] != s[i])
{
cnt += 1;
c = tmp(c);
}
}
}
int main ()
{
cin>>n;
cin>>s;
add();
reverse(s.begin(), s.end());
add();
for(int i=1;i<n;i++)
{
if((s[i-1] == 'A' && s[i] == 'B')
|| (s[i-1] == 'B' && s[i] == 'A'))
cnt -= 1;
}
cout<< (long long)n*(n-1)/2 - cnt<<endl;
return 0;
}
补充: 统计不合法字符串的简单方法
- 识别出连续子串(如"AAA", "BBBB"等),检查其两侧是否有字符。
- AB、BA会被算两次,为了防止重复我们应该只考虑一次(仅仅在左侧有字符时考虑或者仅仅在右侧有字符时考虑)。
代码
#include <iostream>
using namespace std;
int n;
char s[1000000];
int main ()
{
cin>>n;
cin>>s;
long long ans = (long long)n * (n-1) / 2, l = 0;
for(int i=0;s[i];i++)
{
if(s[l] != s[i+1]) //找到一段连续子串
{
if(s[i+1]) ans -= i-l; //如果右侧有字符(不考虑BA或AB)
if(l) ans -= i-l+1; //如果左侧有字符(考虑BA或AB)
l = i+1; //寻找下一段连续子串
}
}
cout<<ans<<endl;
return 0;
}