码迷,mamicode.com
首页 > 其他好文 > 详细

NYOJ491幸运三角形

时间:2017-08-20 21:26:15      阅读:322      评论:0      收藏:0      [点我收藏+]

标签:highlight   字符   backtrace   txt   通过   space   back   bsp   tac   

 

幸运三角形

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

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

                                           技术分享

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

 
输入
有多组测试数据(少于20组)。
每行含一个整数n(0<n<20)。
输出
输出相应的幸运三角形个数。
样例输入
3
4
样例输出
4
6
/*#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
int n, cnt; 
int a[25]; 
int check()//每次总是觉得这个check函数是最难得 
{ 
    int i, j, t1, t0; 
    t1 = 0; 
    t0 = 0; 
    for(j = n - 1; j >= 0; j--)//外层循环是有几层,即循环的n次 
    { 
        for(i = 0; i <= j; i++)//里层循环式一层有几个字符,即有j个 
        { 
            if(a[i] == 1)//计数是+还是- 
                t1++; 
            else 
                t0++; 
            if(i > 0)//因为是用的一维数组存的,所以这里的主要作用是把这个一维数组变成下一层所需要的样式 
            { 
                if(a[i] == a[i - 1])//符号相同则是+ 
                    a[i - 1] = 1; 
                else//否则是- 
                    a[i - 1] = 0; 
            } 
        } 
    } 
    if(t1 == t0) 
        return 1; 
    return 0; 
} 
void dfs(int x) 
{ 
    if(x == n) 
    { 
        if(check() == 1) 
            cnt++; 
        return ;//开始把return放在if里面了一直出不来结果,真是笨笨的脑袋 
    } 
    a[x] = 1;//这里并没有往常一样有if判断了,而是直接深搜了 
    dfs(x + 1); 
    a[x] = 0;//这里回溯回来的时候继续深搜下去,思路还是比较清晰的 
    dfs(x + 1); 
} 
int main() 
{ 
    while(scanf("%d", &n) != EOF) 
    { 
        cnt = 0; 
        dfs(0); 
        printf("%d\n", cnt); 
    } 
    return 0; 
} 
*/  打表
#include <stdio.h>  
int a[21] = {0,0,0,4,6,0,0,12,40,0,0,171,410,0,0,1896,5160,0,0,32757};//打表最好不要用for循环  
int main()  
{  
    int n;  
    while(scanf("%d", &n) != EOF)  
    {  
        printf("%d\n", a[n]);  
    }  
    return 0;  
}  

  OJ平台最优代码:

#include"iostream"  
#include<cstring>  
#include<stdio.h>  
#include<time.h>  
using namespace std;  
typedef unsigned char uchar;  
  
char cc[2]={‘+‘,‘-‘};   //便于输出  
int n,                  //第一行符号总数  
    half,               //全部符号总数一半  
    counter;            //1计数,即“-”号计数  
      
char **p;               //符号存储空间      
long sum;               //符合条件的三角形计数  
  
//t,第一行第t个符号  
void Backtrace(int t)  
{  
    int i, j;  
      
    if( t > n )  
        sum++;  
    else  
       for(i=0; i<2; ++i)  
       {  
            p[1][t] = i;//第一行第t个符号  
            counter += i;       //“-”号统计  
            for(j=2; j<=t; ++j)  //当第一行符号>=2时,可以运算出下面行的某些符号  
            {  
                p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];//通过异或运算下行符号  
                counter += p[j][t-j+1];                       
            }  
            if( (counter <= half) && ( t*(t+1)/2 - counter <= half) )//若符号统计未超过半数,并且另一种符号也未超过半数  
                Backtrace(t+1);         //在第一行增加下一个符号     
            //回溯,判断另一种符号情况  
            for(j=2; j<=t; ++j)    
                counter -= p[j][t-j+1];        
            counter -= i;  
       }  
}  
  
int main()  
{    
    freopen("input.txt","r",stdin);  
    while(scanf("%d", &n) != EOF)  
    {  
    counter = 0;  
    sum = 0;  
    half = n*(n+1)/2;  
      
    if( half%2 == 0 )  
    {//总数须为偶数,若为奇数则无解  
        half /= 2;  
        p = new char *[n+1];  
        for(int i=0; i<=n; ++i)  
        {  
           p[i] = new char[n+1];  
           memset(p[i], 0, sizeof(char)*(n+1));  
        }     
        Backtrace(1);  
    }     
    printf("%d\n", sum);}  
    return 0;  
}          

  程序用一个t表示第一行中n个数中的第几个数,用第一重循环来赋值n个数的0或1值。然后再用一重循环,不断去更新每行未更新的。因为t不断加1,j每次都是从2开始,所以当t增大,当到j行时,明显j每次只是重复2-t之中,所以这样就实现了当第一行每增加一个数,都能补全为一个三角形了。

NYOJ491幸运三角形

标签:highlight   字符   backtrace   txt   通过   space   back   bsp   tac   

原文地址:http://www.cnblogs.com/521LOVE/p/7401082.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!