zoukankan      html  css  js  c++  java
  • NYOJ491 幸运三角形

     

    幸运三角形

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:3
     
    描述

            话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒置的金字塔形状,除第一层外(第一层为所有可能情况),每层形状都由上层决定,相邻的符号相同,则下层的符号为‘+’,反之,为‘-’;如下图所示(n = 3 时的两种情况):

                                               

    如果图中的两种符号个数相同,那这个三角形就是幸运三角形,如上图中的图(2).

     
    输入
    有多组测试数据(少于20组)。
    每行含一个整数n(0<n<20)。
    输出
    输出相应的幸运三角形个数。
    样例输入
    3
    4
    
    样例输出
    4
    6


    代码一:  TLE 
     1 #include <cstdio>
     2 #include <iostream>
     3 
     4 using namespace std;
     5 int a[25];
     6 int n, cnt;
     7 
     8 bool judge()
     9 {
    10     int t0, t1;
    11     t0 = t1 = 0;
    12     for(int end = n; end >= 1; --end)
    13     {
    14         for(int i = 1; i <= end; ++i)
    15         {
    16             if(a[i] == 1)
    17                 ++t1;
    18             else
    19                 ++t0;
    20             if(t1 > ((n+1)*n>>1) || t1 > ((n+1)*n>>1))  //剪枝 
    21                 return false;
    22             if(i > 1)
    23             {
    24                 if(a[i] == a[i-1])
    25                     a[i-1] = 1;
    26                 else
    27                     a[i-1] = 0;
    28             }
    29         }
    30     }
    31     if(t0 == t1)
    32         return true;
    33     return false;
    34 }
    35 
    36 void DFS(int cur)
    37 {
    38     if(cur > n)
    39     {
    40         if(judge())
    41             ++cnt;
    42         return;
    43     }
    44     a[cur] = 1;
    45     DFS(cur+1);
    46     a[cur] = 0;
    47     DFS(cur+1);
    48 }
    49 
    50 int main()
    51 {
    52     while(scanf("%d", &n))
    53     {
    54         if(((n+1)*n>>1) & 1)
    55         {
    56             printf("0\n");
    57             continue;
    58         }
    59         cnt = 0;
    60         DFS(1);
    61         printf("%d\n", cnt);
    62     }
    63     return 0;
    64 }
    View Code

    代码二:打表-----AC 

     1 #include <cstdio>
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     int ans[21] = {0,0,0,4,6,0,0,12,40,0,0,171,410,0,0,1896,5160,0,0,32757,59984};
     9     int n;
    10     while(~scanf("%d", &n))
    11     {
    12         printf("%d\n", ans[n]);
    13     }
    14     return 0;
    15 } 
    View Code

    代码三:----copy最优代码(边计算边回溯,避免了重复计算,很给力啊)

     1 #include"iostream"
     2 #include<cstring>
     3 #include<stdio.h>
     4 #include<time.h>
     5 using namespace std;
     6 typedef unsigned char uchar;
     7 
     8 //char cc[2]={'+','-'};    //便于输出
     9 int n,                     //第一行符号总数
    10     half,                 //全部符号总数一半
    11     counter;             //1计数,即  '-' 号计数
    12     
    13 char **p;                //符号存储空间    
    14 long sum;                //符合条件的三角形计数
    15 
    16 //t,第一行第 t个符号
    17 void Backtrace(int t)
    18 {
    19     int i, j;
    20     
    21     if( t > n )
    22         sum++;
    23     else
    24     {
    25        for(i=0; i<2; ++i)  //只取  0('+')  或者  1('-')
    26        {
    27             p[1][t] = i;   //第一行第 t个符号
    28             counter += i;        //'-'号统计
    29             for(j=2; j<=t; ++j)    //当第一行符号 >=2时,可以运算出下面行的某些符号(第一行有几个数就可以相应往下计算几行,每次计算过的就不用重复计算) 
    30             {
    31                 p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];//通过异或运算下行符号
    32                 counter += p[j][t-j+1];                        
    33             }
    34             if( (counter <= half) && ( t*(t+1)/2 - counter <= half) )//若符号统计未超过半数,并且另一种符号也未超过半数
    35                 Backtrace(t+1);            //在第一行增加下一个符号    
    36             //回溯,判断另一种符号情况
    37             for(j=2; j<=t; ++j)    
    38                 counter -= p[j][t-j+1];         
    39             counter -= i;
    40        }
    41     }
    42 }
    43 
    44 int main()
    45 {  
    46     while(scanf("%d", &n) != EOF)
    47     {
    48         counter = 0;
    49         sum = 0;
    50         half = n*(n+1)/2;
    51         
    52         if( half%2 == 0 )//总数须为偶数,若为奇数则无解
    53         {
    54             half /= 2;
    55             p = new char *[n+1];
    56             for(int i=0; i<=n; ++i)
    57             {
    58                p[i] = new char[n+1];
    59                memset(p[i], 0, sizeof(char)*(n+1));
    60             }   
    61             Backtrace(1);
    62         }    
    63         printf("%d\n", sum);
    64     }
    65     return 0;
    66 }         
    View Code
  • 相关阅读:
    md5() 加密password,数据库字段长度要够(eg:varchar(30)),丢失部分数据,导致登录不上
    PHP $_SERVER (eg:REMOTE_ADDR)
    u3000是全角空格的16进制Unicode编码。 xa0
    Javascript验证Textarea中是否有值/javascript验证select是否为空(是否选择)
    /[u4e00-u9fa5]/汉字的正则匹配
    mysql_error() mysql_errno() 错误代码1064
    javascript正则表达式验证身份证
    javascript与php中的正则表达式
    停课集训 12.1
    bzoj1227 组合数学+bit
  • 原文地址:https://www.cnblogs.com/dongsheng/p/3138607.html
Copyright © 2011-2022 走看看