计蒜客/阿里的新游戏

阿里九游开放平台近日上架了一款新的益智类游戏——成三棋。成三棋是我国非常古老的一个双人棋类游戏,其棋盘如下图所示:
这里写图片描述

成三棋的棋盘上有很多条线段,只能在线段交叉点上放入棋子。我们可以用坐标系来描述棋盘:
这里写图片描述

如果一条线段上的三个交叉点都被同一玩家的棋子占据的话,则称这条线段被该玩家 成三。现在,小红和小明两人在游戏平台上下棋,其中小红的棋子是黑色的。请你帮小红计算他成三的线段数。

样例对应的棋盘如下:
这里写图片描述

输入格式

输入第一行两个整数 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
我的思路比较简单,先把输入的数据存放在二维数组a[10][2]里,然后分别以行、列的方式遍历该数组,对该数组中横、纵坐标相同的点进行分类,-3到3的7个数字,num[7]对在每一条纵线和横线上的点进行统计,从而知道每一个线段方向上有几个点,b[7][6]则是记录横坐标或者纵坐标相同的点记录另一维的数字,以便之后判断是否在一条线段上。
在judge函数里,如果一个线段方向上有超过3个点,若这个数字不是0,那么肯定只有三个点,而且这三个点在一条线段上(从图里可以看出)。如果这个数字是0,可以对b[i][]里存的数字进行排序,先从小到大,如果前三个数字分别是-3,-2,-1,那么肯定符合要求,再从大到小排序,如果前三个数字分别是3,2,1,也是符合要求的。之所以进行两次排序判断,是因为可能有6个点,在两条线段上。

代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

int Point_num,useless,a[10][2]={-99},b[7][6]={-99},so=0;
int num[7]={0};
void judge()
{
    int *p,i;   
    for(i=0;i<7;i++)
    {
        if(num[i]>2)
        {
            p=b[i];
            if(i!=3)
                so++;
            else
            {
                sort(p,p+num[i],less<int>());
                if(p[0]==-3 && p[1]==-2 &&p[2]==-1)
                    so++;
                sort(p,p+num[i],greater<int>());
                if(p[0]==3 && p[1]==2 &&p[2]==1)
                    so++;
            }   
        }
    }

}
void d(int c)
{
    int i,j;
    for(i=0;i<7;i++)
    {
        num[i]=0;
        for(j=0;j<6;j++)
            b[i][j]=-99;
    }

    for(i=0;i<Point_num;i++)
    {
        j=a[i][c]+3;
        b[j][num[j]++]=a[i][1-c];
    }
}
int main(){
    int i,j,k;
    cin>>Point_num>>useless;
    for(i=0;i<Point_num;i++)
        cin>>a[i][0]>>a[i][1];
    for(i=0;i<useless;i++)
        cin>>j>>k;
    for(i=0;i<2;i++)
    {
        d(i);
        judge();    
    }
    cout<<so;
} 

发布了10 篇原创文章 · 获赞 6 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_35565669/article/details/79432599
今日推荐