• luogu1556 幸福的路


    注意到(nle10),所以枚举经过的拐弯牛的所有排列。

    注意到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
    ", ans);
        return dou;
    }
    

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

  • 相关阅读:
    JavaScript基础——第四章,JavaScript对象及初识面向对象
    JavaScript基础——第三章,JavaScript操作DOM对象
    Spring框架概述
    swagger注释@API详细说明
    JavaScript基础——第二章,JavaScript操作BOM对象
    JavaScript基础——第一章,基础
    JAVA基础——第二章,变量,数据类型和运算符
    JAVA基础——第一章,初识JAVA
    setinterval取消,element使用正则,git上传,js倒计时
    js复习
  • 原文地址:https://www.cnblogs.com/oier/p/9596631.html
Copyright © 2020-2023  润新知