HDU2510符号三角形(位运算打表)

题意:中文题面。


思路:观察规律,相同得‘+’,不同得‘-’,跟异或运算很相似,可用0代表‘+’,1代表‘-’。第一层有n位,n不大于24,因此可用n位二进制数来表示当前一层的状态,数位上的0和1分别代表相应的符号,求下一层的状态时只需要当前层的各位数字两两异或即可组成下一层的状态,每向下一层,位数就减一。


由于n位二进制数共有2的n次方种情况,先求出最大的一种即2^n-1,然后依次-1枚举到0即可。二进制不熟练,还有多重循环,写的时候晕头转向,还好写对了。


打表代码:

#include<bits/stdc++.h>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF  0x3f3f3f3f
typedef long long  LL;
int ans[25],a[25];//一个记录结果,一个记录中间状态
int main(){
    memset(ans,0,sizeof(ans));
    for(int i=1;i<=24;++i){//最外层决定顶层位数
        a[1]=(1<<i)-1;//最大值
        while(a[1]>=0){//从最大值开始往下枚举第一层的状态
            for(int j=2;j<=i;++j){//求出下面n-1层的状态
                a[j]=0;
                for(int k=0;k<(i-j+1);++k){
                    a[j]|=((((a[j-1]>>k)&1)^((a[j-1]>>(k+1))&1))<<k);
                }
            }
            int cnt1=0,cnt2=0;//计数
            for(int j=1;j<=i;++j){//遍历每一层的状态
                for(int k=0;k<i-j+1;++k){//统计当前层
                    if((a[j]>>k)&1)++cnt1;
                    else ++cnt2;
                }
            }
            if(cnt1==cnt2)++ans[i];
            --a[1];
        }
    }
    for(int i=1;i<25;++i)
        printf("%d\n",ans[i]);
}


AC代码:


#include<bits/stdc++.h>
using namespace std;
#define INF  0x3f3f3f3f
typedef long long  LL;
int main(){
    int n,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};
    while(scanf("%d",&n),n){
        printf("%d %d\n",n,ans[n]);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值