HDU——2510 符号三角形(位运算 + 打表)

Problem Description

符号三角形的 第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“,2个异 号下面是”-“ 。计算有多少个不同的符号三角形,使其所含”+“ 和”-“ 的个数相同 。 n=7时的1个符号三角形如下:
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+

Input

每行1个正整数n <=24,n=0退出.

Output

n和符号三角形的个数.

Sample Input

15
16
19
20
0

Sample Output

15 1896
16 5160
19 32757
20 59984

解题思路:

“2个同号下面是‘+’,2个异 号下面是‘-’”,类似于位运算中的异或。
直接用‘+’,‘-’来进行计算,多少有点麻烦,所以选择用 0 代表 ‘+’ , 用 1 代表 ‘-’ 。
本题主要涉及的内容主要是 位运算相关知识 ,讲解 位运算

代码:

//位运算
//两位相同则为 0  , 不同为 1。
//n <= 24 , 打表
#include <cstdio>
using namespace std;

//求取过程
int ans[30] ;
int a[30];
int main(){
    int n , i , j , k ;
        for(i = 1 ; i <=24 ; i ++){   // n 总共有 24 种情况
            //遍历 n  = 1 ~ 24 的各种情况 , 其中每种情况下也分为2^n中不同的取值情况
            a[1] = (1 << i) - 1;   //最大值
            while(a[1] >= 0){   //依次遍历 2^n种情况
                for( j = 2 ; j <= i ; j ++){  //求出 n-1 到 1 层的取值情况
                    a[j] = 0;
                    for(k = 0 ; k < i - j + 1 ; k ++)  // i-j+1表示当前该层的数字的个数
                    // k 表示当前求取的数所在的位
                    a[j] = a[j] | ( (a[j-1]>>k)&1 ^ (a[j-1]>>k+1)&1 ) << k;   //从后向前求取
                }

                int ans1 = 0 , ans2 = 0;
                for(j = 1 ; j <= i ; j ++){   //统计个数
                    for(k = 0 ; k < i - j + 1 ; k ++){
                        if((a[j] >> k)&1)  //为 0;
                            ans1 ++;
                        else
                            ans2 ++;
                    }
                }
                if(ans1 == ans2)
                    ans[i] ++;
                a[1] --;
            }
            printf("%d ",ans[i]);
        }

    return 0;
}

运行结果:这里写图片描述
注:直接提交上述代码肯定是会超时的 , 所以直接把上述代码的结果保存在一个结果数组里面,以下为AC代码 。

AC代码

int ans[25] = {0 , 0 , 0 , 4 , 6 , 0 , 0 , 12 , 40 , 0 , 0 , 171 , 410 , 0 , 0 , 1896 , 5160 , 0 , 0 , 32757 , 59984 , 0 , 0 , 431095 , 822229};

int main(){
    int n;
    while(scanf("%d" , &n) != EOF && n){
        printf("%d %d\n",n , ans[n]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值