2017 计蒜之道 初赛 第一场 A. 阿里的新游戏

3 篇文章 0 订阅
3 篇文章 0 订阅

这里写图片描述
一道枚举题目, 枚举所有的组合,然后根据这些组合判断棋子在不在同一条线上

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
    int x, y;
};

node ss[100], tt[4];
int jj;
int is_node(node q)//返回vis数组最小下标
{
    for(int i = 0; i<= 100; i++)
        if(q.x == ss[i].x && q.y == ss[i].y) return i;
    return 0;
}
bool cmpx(const node &a, const node &b){return a.x < b.x;}
bool cmpy(const node &a, const node &b){return a.y < b.y;}
int is_okx(node tt[4])//对于ok==0时有特殊遗漏的判断
{
    node qq[4];
    for(int i = 1; i <= 3; i++) qq[i] = tt[i];
    sort(qq+1, qq+4, cmpx);
    if(qq[1].x+qq[3].x == -1 || qq[1].x+qq[3].x == 1) return 1;
    return 0;
}
int is_oky(node tt[4])
{
    node qq[4];
    for(int i = 1; i <= 3; i++) qq[i] = tt[i];
    sort(qq+1, qq+4, cmpy);
    if(qq[1].y+qq[3].y == -1 || qq[1].y+qq[3].y == 1) return 1;
    return 0;
}
int n, m;
void dfs(int cur)
{
    if(cur > 3)
    {
        if(tt[1].x == tt[2].x && tt[1].x == tt[3].x && tt[3].x == tt[2].x)
        {
            int ok = tt[1].y + tt[2].y + tt[3].y;
            if(ok == 0 || ok == -6 || ok == 6)
            {
                if(is_oky(tt)) return;
                jj++;
            }
            return;
        }
        if(tt[1].y == tt[2].y && tt[1].y == tt[3].y && tt[3].y == tt[2].y)
        {
            int ok = tt[1].x + tt[2].x + tt[3].x;
            if(ok == 0 || ok == -6 || ok == 6)
            {
                if(is_okx(tt)) return;
                jj++;
            }
            return;
        }
        return;
    }
    int s = (cur == 1 ? 1 : is_node(tt[cur-1])+1);
    //保证最小序枚举组合
    for(int i = s; i <= n; i++)
    {
        tt[cur] = ss[i];
        dfs(cur+1);
    }
}
int main()
{
    while(cin >> n >> m && n >= 3 && m >= 3 && n <= 9 && m <= 9)
    {
        memset(tt, 0, sizeof(tt));
        memset(ss, 0, sizeof(ss));
        jj = 0;
        for(int i = 1; i <= n; i++)
            cin >> ss[i].x >> ss[i].y;
        int a, b;
        while(m--)
            cin >> a >> b;
        dfs(1);
        cout << jj << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值