文章首发自进击的ACMer
写在前面
这是第一次参加这种网络赛,点开题目就是浓浓的广告风,全是阿里系列,听群巨巨说下一场是百度系列
过题情况
第一题比较水,暴力枚举,第二题中和困难基本上卡了所有人1200+的人才过了不到10个。个人比较菜排了309下一场接着战吧!!
第一题:阿里的新游戏
阿里九游开放平台近日上架了一款新的益智类游戏——成三棋。成三棋是我国非常古老的一个双人棋类游戏,其棋盘如下图所示:
成三棋的棋盘上有很多条线段,只能在线段交叉点上放入棋子。我们可以用坐标系来描述棋盘:
如果一条线段上的三个交叉点都被同一玩家的棋子占据的话,则称这条线段被该玩家 成三。现在,小红和小明两人在游戏平台上下棋,其中小红的棋子是黑色的。请你帮小红计算他成三的线段数。
样例对应的棋盘如下:
输入格式
输入第一行两个整数 n,m(3 \le n, m \le 9)n,m(3≤n,m≤9),nn 表示小红的棋子数,mm 表示小明的棋子数。
接下来 nn 行输入小红的棋子坐标。
接下来 mm 行输入小明的棋子坐标。
输入保证坐标合法,并且棋子之间不重合。
输出格式
输出小红成三的线段数。
样例输入
6 3
-1 0
-2 0
-3 0
-1 -1
-1 1
1 0
0 2
0 3
2 2
样例输出
2
思路:
这道题很水,纯粹是520强行组cp的,刚开始想有没有什么数学方法做,但是发现刚过8分钟就有人做出来了,那就开始暴力吧,枚举所有三条线相连的情况。。。。。
代码:
#include <iostream>
using namespace std;
int main()
{
int n,m,sum=0;
int x,y;
cin>>n>>m;int a[10][10]={0};
for(int i=0;i<n;i++)
{
cin>>x>>y;
x+=3;
y+=3;
a[x][y]=1;
}
for(int i=0;i<m;i++)
cin>>x>>y;
if(a[0][0]&&a[3][0]&&a[6][0])
sum++;
if(a[1][1]&&a[3][1]&&a[5][1])
sum++;
if(a[2][2]&&a[3][2]&&a[4][2])
sum++;
if(a[0][3]&&a[1][3]&&a[2][3])
sum++;
if(a[4][3]&&a[5][3]&&a[6][3])
sum++;
if(a[2][4]&&a[3][4]&&a[4][4])
sum++;
if(a[1][5]&&a[3][5]&&a[5][5])
sum++;
if(a[0][6]&&a[3][6]&&a[6][6])
sum++;
if(a[0][0]&&a[0][3]&&a[0][6])
sum++;
if(a[1][1]&&a[1][3]&&a[1][5])
sum++;
if(a[2][2]&&a[2][3]&&a[2][4])
sum++;
if(a[3][0]&&a[3][1]&&a[3][2])
sum++;
if(a[3][4]&&a[3][5]&&a[3][6])
sum++;
if(a[4][2]&&a[4][3]&&a[4][4])
sum++;
if(a[5][1]&&a[5][3]&&a[5][5])
sum++;
if(a[6][0]&&a[6][3]&&a[6][6])
sum++;
cout<<sum<<endl;
return 0;
}
第二题:阿里天池的新任务
阿里“天池”竞赛平台近日推出了一个新的挑战任务:对于给定的一串 DNA 碱基序列 tt,判断它在另一个根据规则生成的 DNA 碱基序列 ss 中出现了多少次。
首先,定义一个序列 ww:
接下来,定义长度为 nn 的 DNA 碱基序列 ss(下标从 00 开始):
输入格式
输出格式
输出一个整数,为 t 在 S 中出现的次数。
样例说明
对于第一组样例,生成的 ss 为TTTCGGAAAGGCC。
样例输入1
13 2 5 4 9
AGG
样例输出1
1
样例输入2
103 51 0 40 60
ACTG
样例输出2
5
思路:
乍一看,前面又是这个公式那个公式的差点儿被唬住了,仔细一看就是字符串匹配,只不过要自己生成第一个串,第一个难度数据量也不是很大,直接KMP上去撸(后来看群里也有人说用hash直接撸随后学学试一下),中等和困难的就撸不动了。刚开始数组开不出来,就用滚动数组边用边生成,结果到第五组数据就超时了。看了官方给的题解原来要用什么a,n互质的原理来减少计算次数什么的,还不是很懂,等明白了在贴代码。官方题解链接传送门
简单难度代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int n,a,b,l,r,wi,m;
char s[1000009],t[1000009];
int neaxttt[1000009];
int w(int i)
{
if(i==0)
return b;
return (wi+a)%n;
}
char S(int i)
{
wi=w(i);
if(wi<=r&&wi>=l)
{
if(wi%2)
return 'T';
return 'A';
}
else
{
if(wi%2)
return 'C';
return 'G';
}
}
void Neaxt(char b[])
//部分匹配表的实现
{
int i,j;
i=0;
j=-1;
neaxttt[i]=j;
while(i<m)
{
if(j==-1||b[i]==b[j])
{
i++;
j++;
neaxttt[i]=j;
}
else
j=neaxttt[j];
}
return ;
}
int KMP(char a[],char b[])//kmp匹配算法
{
int i,j,sum=0;
i=j=0;
Neaxt(b);//先计算部分匹配表
while(i<n)
{
if(j==-1||a[i]==b[j])
{
i++;
j++;
if(j==m)
sum++;//找到目标字符串,数量加一。
}
else
j=neaxttt[j];//a[i]与b[j]不匹配,查表需要跳过的字符个数。
}
return sum;//返回匹配数量
}
int main()
{
scanf("%d %d %d %d %d",&n,&a,&b,&l,&r);
for(int i=0;i<n;i++)
s[i]=S(i);
s[n]=0;
scanf("%s",t);
m=strlen(t);
cout<<KMP(s,t)<<endl;
return 0;
}