2017计蒜之道第一场题解

文章首发自进击的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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值