问题 T1 瑞神的序列
问题描述
瑞神的数学一向是最好的,连强大的咕咕东都要拜倒在瑞神的数学水平之下,虽然咕咕东很苦
恼,但是咕咕东拿瑞神一点办法都没有。
5.1期间大家都出去玩了,只有瑞神还在孜孜不倦的学习,瑞神想到了一个序列,这个序列长度为
,也就是一共有 个数,瑞神给自己出了一个问题:数列有几段?
段的定义是连续的相同的最长整数序列
题目分析
这个题目比较简单,只需要遍历一次,把每一个和上一个数字不一样的,使其num+1,最后再输出我们计算的数目+1即可。
代码
#include<iostream>
using namespace std;
int num,shu1,shu2,n;
int main()
{
num=0;
scanf("%d",&n);
scanf("%d",&shu1);
num++;
for(int i=1;i<n;i++)
{
scanf("%d",&shu2);
if(shu2!=shu1)
{
num++;
shu1=shu2;
}
}
printf("%d\n",num);
return 0;
}
问题T2消消乐
问题描述
Q老师是个很老实的老师,最近在积极准备考研。Q老师平时只喜欢用Linux系统,所以Q老师的电
脑上没什么娱乐的游戏,所以Q老师平时除了玩Linux上的赛车游戏SuperTuxKart之外,就是喜欢
消消乐了。
游戏在一个包含有 n 行 m 列的棋盘上进行,棋盘的每个格子都有一种颜色的棋子。当一行或一列
上有连续三个或更多的相同颜色的棋子时,这些棋子都被消除。当有多处可以被消除时,这些地
方的棋子将同时被消除。
一个棋子可能在某一行和某一列同时被消除。
由于这个游戏是闯关制,而且有时间限制,当Q老师打开下一关时,Q老师的好哥们叫Q老师去爬
泰山去了,Q老师不想输在这一关,所以它来求助你了!!
输入格式
输入第一行包含两个整数n,m,表示行数和列数
接下来n行m列,每行中数字用空格隔开,每个数字代表这个位置的棋子的颜色。数字都大于0.
输出格式
输出n行m列,每行中数字用空格隔开,输出消除之后的棋盘。(如果一个方格中的棋子被消除,
则对应的方格输出0,否则输出棋子的颜色编号。)
题目分析
由于这个棋盘不是很大,所以我采用了暴力遍历法,就是再拿一个数组来记录那个位置上的棋子是否被消除了,每行每列都单独扫描一遍,如果有连着3个及以上的棋子,那就消除它们,将记录的数组更新,最后输出的时候每次看一眼是不是被消除了,然后直接输出对应的就行。
代码
#include<iostream>
using namespace std;
int n,m;
int chess[31][31];
int vis[31][31];
void xiao(int x,int xu)
{
int shu,number=1;
if(xu==1)
{
shu=chess[x][0];
for(int i=1;i<m;i++)
{
if(chess[x][i]==shu)
number++;
else
{
shu=chess[x][i];
number=1;
}
if(number>=3)
{
vis[x][i]=1;
vis[x][i-1]=1;
vis[x][i-2]=1;
}
}
}
else
{
shu=chess[0][x];
for(int i=1;i<n;i++)
{
if(chess[i][x]==shu)
number++;
else
{
shu=chess[i][x];
number=1;
}
if(number>=3)
{
vis[i][x]=1;
vis[i-1][x]=1;
vis[i-2][x]=1;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&chess[i][j]);
vis[i][j]=0;
}
}
for(int i=0;i<n;i++)
xiao(i,1);
for(int i=0;i<m;i++)
xiao(i,2);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(vis[i][j]==1)
printf("0");
else
printf("%d",chess[i][j]);
if(j!=m-1)
printf(" ");
}
printf("\n");
}
return 0;
}
问题 T4 咕咕东学英语
问题描述
今天TT打算教咕咕东字母A和字母B,TT给了咕咕东一个只有大写A、B组成的序列,让咕咕东分辨这些字母。
咕咕东问TT这个字符串有多少个子串是Delicious的。
Delicious定义:对于一个字符串,我们认为它是Delicious的当且仅当它的每一个字符都属于一个
被完整包含于字符串的大于1的回文子串中。
输入第一行一个正整数n,表示字符串长度
接下来一行,一个长度为n只由大写字母A、B构成的字符串。
输出仅一行,表示符合题目要求的子串的个数。
题目分析
一个字符串如果它的任意一个字符和附近的任意数目的字符组成回文,那么这个字符串就是合格的,我们要做的就是把这个合格的字符串数目记录下来。
根据多次实验结果,只有AAAAB,BAAAAA,BBBBBA,和ABBBBBB四种不是合格的子字符串,所以只需要遍历每一种结果,看他是不是以上四种情况,是的话就不算入内就行。
我的做法就是计算所有的结果数目,然后去掉那些不可能的情况即可。
代码
#include<iostream>
using namespace std;
//#include<string.h>
//#include<algorithm>
char zi[300010];
long long shu[300010];
long long num=0;
long long m;
int main()
{
cin>>m;
cin>>zi;
char a;
long long n=0;
a=zi[0];
num=(long long)((m-1)*m/2);
for(long long i=1;i<m;i++)//右边单
{
if(zi[i]!=zi[i-1])
{
num=num-(i-n-1);
n=i;
}
}
n=m-1;
for(long long i=m-2;i>=0;i--)//左边单
{
if(zi[i]!=zi[i+1])
{
num=num-(n-i);
n=i;
}
}//AABB中,去掉AAB和AB ABB,AB重复
cout<<num;
}
遇到的问题
主要是没有找到规律,最开始以为是个数学问题,采用了窗口的思维,然后部分答案是对的,没有考虑周全。