Processing math: 0%

luogu1556 幸福的路

注意到n\le10,所以枚举经过的拐弯牛的所有排列。

注意到STL是一个好东西,所以我这里偷懒直接使用了next_permutation

枚举所有n的排列,对于每一个排列也就是经过拐弯牛的顺序,我们要判断两点:

  • 一个是相邻的两个牛(以及从(0,0)到第一个牛,和从最后一个牛到(0,0))的路径是否平行坐标轴,这个直接判相等即可。
  • 还有一个是要判断经过每一头牛是否拐弯了,对于第p头牛我们可以计算从第p-1头牛(当p=1就是原点)到第p头牛的路径向量,和第p头牛到第p+1头牛(当p=n就是远点)的路径向量,通过两个向量的点积就可以方便地判断是否转弯,由于我们已经判断了是否垂直平行坐标系,所以点积为0说明转弯90度,点积小于0说明掉头,点积大于0说明没有转弯。

然后答案就是合法的n的排列的个数

#include <bits/stdc++.h>
using namespace std;

struct coord
{
    int x, y;
}c[12];

int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int n, ans;

bool work()
{
    //上一次的坐标
    int lx = 0, ly = 0;
    for (int i = 0; i < n; i++)
    {
        int p = a[i];
        int x = c[p].x, y = c[p].y;//本次的坐标
        int nx = c[a[i + 1]].x, ny = c[a[i + 1]].y;//下一次的坐标
        //判断路径是否平行于坐标轴
        if(((lx == x) || (ly == y)) == 0)
            return false;
        if(((nx == x) || (ny == y)) == 0)
            return false;
        //1和2是两个向量
        int x1 = x - lx, y1 = y - ly;
        int x2 = nx - x, y2 = ny - y;
        if((x1 * x2 + y1 * y2 > 0))//计算点积
        {
            return false;
        }
        lx = x;//更新坐标
        ly = y;
    }
    return true;
}

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%d%d", &c[i].x, &c[i].y);
    a[n] = n;
    do
        ans += work();
    while (next_permutation(a, a + n));
    printf("%d\n", ans);
    return dou;
}

让我们一起膜拜大佬林瑞堂@olinr

posted @   ghj1222  阅读(213)  评论(0编辑  收藏  举报
编辑推荐:
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
阅读排行:
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· 语音处理 开源项目 EchoSharp
· 《HelloGitHub》第 106 期
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 使用 Dify + LLM 构建精确任务处理应用
点击右上角即可分享
微信分享提示