zoukankan      html  css  js  c++  java
  • 理工 校赛 题

    lzp穿鞋带的理论方法

    发布时间: 2017年12月11日 14:01   最后更新: 2017年12月11日 14:46   时间限制: 1000ms   内存限制: 128M

    对于鞋,lzp有一套奇怪的穿鞋带理论:

    0.鞋带孔之间的鞋带不能是弯的,即鞋带穿过两鞋带孔时必须绷直。

    1.鞋带必须从最前面的一头左端穿入,并从最前面右端穿出,如图所示为一些普qi通pa的穿鞋带方法,○表示鞋带孔,直线表示鞋带。

    c7d12bb4edd31959a7136abbddc237e5.png14ac3b41ef97c2b7419b4626b5ea2d9b.png

    shoe5.png

    2.穿鞋带时,必须左右交替,如上图所示

    3.穿完的鞋带必须存在m个以上的交点,上图左边的共有四个交点,右边的有九个交点。lzp的鞋保证所有交点都只被鞋带经过两次。

    现在,lzp想知道,对于每只纵向排列着n对鞋带孔的鞋,有几种穿鞋带方案符合他的理论(上图中n=5)

    第一行输入组数T(T<=10)
    每组数据输入两个数n(1<=n<=7),m(0<=m<=1000)

    对于每组数据输出一行,符合lzp的理论的穿鞋带方案数

    7
    5 4
    5 9
    3 2
    1 0
    3 6
    7 10
    6 20
    576
    540
    4
    1
    1
    518269
    10221

    题目分析 : 每次只能重一个点穿过,并且左右交替,点数不多 最多只有7个,那不就是暴力吗,想想要怎么暴力,每次可以交替枚举出所有可能的边,枚举出所有可能的边以后,
    在判断当前的这些边总共有多少个交点,怎么判断两个点是不是相交呢,如果给两列点瞬时标上号,那么(a[1]-a[2])*(b[1]-b[2]) < 0,则说明两条线是相交的,自己可以举几个例子验证一下。

    代码示例 :
    const int eps = 1e6+5;
    const double pi = acos(-1.0);
    const int inf = 1<<29;
    #define Max(a,b) a>b?a:b
    #define Min(a,b) a>b?b:a
    #define ll long long
    
    int p2[20];
    int p1[20];
    
    struct node
    {
        int a, b;
    }pre[eps];
    
    int sign = 1;
    int p;
    ll ans = 0;
    int n, m;
    
    
    bool check(){
        int k = 1;
        for(int i = 2; i <= n; i++){
            pre[k].a = i;
            pre[k++].b = p1[i];
        }    
        for(int i = 1; i <= n; i++){
            pre[k].a = p2[i];
            pre[k++].b = i;
        }
        //printf("k = %d
    ", k);
        int cnt = 0;
        for(int i = 1; i < k; i++){
            for(int j = i+1; j < k; j++){
                if ((pre[i].a - pre[j].a)*(pre[i].b - pre[j].b) < 0){
                    cnt++;
                }
            }
        }
        if (cnt >= m) return true;
        else return false;
    }
    
    void find(int x){
        for(int i = 2; i <= n; i++){
            //if (x == 1) printf("** %d 
    ", sign);
            if (sign && !p2[i]) {
                p2[i] = x;
                sign = 0;
                find(i);
                p2[i] = 0;
                sign = 1;
                
            }
            else if (!sign && !p1[i]){
                p1[i] = x;
                sign = 1;
                p = i;
                find(i);
                p1[i] = 0;
                sign = 0;
            }   
        }
        int t = 0;
        for(int i = 2; i <= n; i++){
            if (p2[i]) t++;
        }
        if (sign && t == n-1) {
            sign = 0;
            p2[1] = p;
            
            if (check()) ans++;
            p2[1] = 0; 
        }
    }
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int t;
        
        
        cin >> t;
        while(t--){
            scanf("%d%d", &n, &m); 
            
            memset(p2, 0, sizeof(p2));
            memset(p1, 0, sizeof(p1));
            ans = 0, sign = 1;
            find(1); 
            printf("%lld
    ", ans);
            
        }
    
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    Core Animation简介
    objective-c 常用函数、变量
    NSString判断纯数字
    自定义对话框AlterView
    IOS 6 自动布局 入门-1(IOS中autolayout和之前版本autoresize的差异)
    真机调试问题 错误集合
    block使用小结、在arc中使用block、如何防止循环引用
    View和viewController的生命周期
    IOS侧滑和webview
    Linker Error、MRC与ARC、导航条背景
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/8029118.html
Copyright © 2011-2022 走看看