【a502】符号三角形问题

Time Limit: 1 second
Memory Limit: 32 MB

【问题描述】

在一般情况下,符号三角形的第一行有n个符号。按照2个同号的下面是“+”号,2个异号的下面是“-”号的规则生成符号三角形。例如:

+ + - + - + +
 + - - - - +
  - + + + -
   - + + -
    - + -
     - -
      +
即是一个由14个“+”号和14个“-”号组成的符号三角形。要求对于给定的n,计算有多少个不同的符号三角形,使其所包含的“+”和“-”的个数相同。要求用回溯法求解此问题。
【输入格式】

仅有一行,包含一个整数N,表示第一行有N个字符。

【输出格式】

仅有一行,不同的符号三角形的个数;当个数为0时,输出“No solution”

【输入样例】

4

【输出样例】

6

【题目链接】:http://noi.qz5z.com/viewtask.asp?ID=a502

【题解】

先用一层dfs枚举第一层的样子;
O(2^n)
然后根据第一层处理出整张图的样子;(也用dfs)
然后用趋近于O(N^2)的时间复杂度
处理出整张图的样子的时候;
可以加一个判断
if (负号或正号个数>(1+n)*n/4) return;
这个剪枝挺强力的吧.
处理的时候可以把所有的符号都移到最左边;左对齐;
a[i][j]由a[i-1][j]和a[i-1][j+1]决定;
(为它们的异或值)
一开始可以加一个判断if (1+n)*n/2为奇数;
那么就不可能有解;
依我对这个平台的了解;
它肯定会出一个(1+n)*n/2为奇数,然后n特别大的数据点。
[斜眼笑]

【完整代码】

#include <cstdio>

int n,ans = 0,temp;
int a[100][100];

void dfs2(int x,int y,int z,int f)
{
    if (z>temp || f > temp)
        return;
    if (x>n)
    {
        ans++;
        return;
    }
    if (y>n-x+1)
    {
        dfs2(x+1,1,z,f);
        return;
    }
    a[x][y] = a[x-1][y] ^ a[x-1][y+1];
    if (a[x][y]==1)
        dfs2(x,y+1,z+1,f);
    else
        dfs2(x,y+1,z,f+1);
}

void dfs1(int x,int z,int f)
{
    if (x > n)
    {
        dfs2(2,1,z,f);
        return;
    }
    a[1][x] = 1;
    dfs1(x+1,z+1,f);
    a[1][x] = 0;
    dfs1(x+1,z,f+1);
}

int main()
{
    scanf("%d",&n);
    if (((1+n)*n/2)&1)
    {
        puts("No solution");
        return 0;
    }
    temp = (1+n)*n/4;
    dfs1(1,0,0);
    if (ans==0)
        puts("No solution");
    else
        printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626693.html