幸运三角形

来源:互联网 发布:淘宝与天猫是一家的吗 编辑:程序博客网 时间:2024/05/02 22:18

幸运三角形

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

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

                                           

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

输入
有多组测试数据(少于20组)。
每行含一个整数n(0<n<20)。
输出
输出相应的幸运三角形个数。
样例输入
34
样例输出
46
这个题目有点坑。。。  我用dfs做超时。。。 然后很多人都是打表过的,从网上找了一段可以过得代码。。。。
这是大神的代码:
#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)  //只取  0('+')  或者  1('-')       {            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(){      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;}

下面是我的代码。。。超时。。。
  #include <iostream>#include <stdio.h>#include <string.h>#include <time.h>using namespace std;int m, count, map[20][20], sum,a = 0;int judge();void dfs(int cur);int main(){while(~scanf("%d", &m)){int start = clock();sum = m * (m + 1) / 2;if(sum % 2 != 0 || m == 0)printf("0\n");else{a = 0;memset(map, 0, sizeof(map));count = 0;dfs(0);printf("%d\n", count);int end = clock();cout<<"time : "<<end - start<<endl;}}return 0;}int judge(){int i;int b = 0;for(i = 1; i < m; i++)for(int j = 0; j < m - i; j++){if(map[i - 1][j] == map[i - 1][j + 1]){map[i][j] = 1;b++;}else map[i][j] = 0;}if((a + b) * 2 == sum)return 1;return 0;}void dfs(int cur){if(cur >= m){if(judge())count++;return ;}map[0][cur] = 1;a++;dfs(cur + 1);map[0][cur] = 0;a--;dfs(cur + 1);}                


0 0
原创粉丝点击