幸运三角形
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒置的金字塔形状,除第一层外(第一层为所有可能情况),每层形状都由上层决定,相邻的符号相同,则下层的符号为‘+’,反之,为‘-’;如下图所示(n = 3 时的两种情况):
如果图中的两种符号个数相同,那这个三角形就是幸运三角形,如上图中的图(2).
-
输入
-
有多组测试数据(少于20组)。
每行含一个整数n(0<n<20)。
输出
- 输出相应的幸运三角形个数。 样例输入
-
3 4
样例输出
-
4 6
-
-
这个题目有点坑。。。 我用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); }
-
有多组测试数据(少于20组)。