zoukankan      html  css  js  c++  java
  • HDU 2510 符号三角形

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2510

     稍微一想,就知道每个符号三角形都是由它的第一行“+,-”号分布决定的,据此可演算出所有分布的三角形,对其进行统计即可。

    同时将一个n行三角形T的+,-号个数分别记为pos_num(n),neg_num(n),其第一行中的+,-号个数记为x(n),y(n),则可得到下式:

    pos_num(n)=x(n)+pos_num(n-1)

    neg_num(n)=y(n)+neg_num(n-1)

    由此,我们可以从n=1开始,利用前面n=k-1的结果,迭代求出n=k的分布情形,然后对n=k的所有分布统计。实现代码如下:

    1 #include <iostream>
    2 #include <vector>
    3  using namespace std;
    4
    5  struct record{
    6 int pos_num;
    7 int neg_num;
    8 record(int pos,int neg)
    9 {
    10 pos_num=pos;
    11 neg_num=neg;
    12 }
    13 };
    14 int power(int base,int pow)
    15 {
    16 int mul=1;
    17 for (int i=0;i<pow;i++)
    18 {
    19 mul*=base;
    20 }
    21
    22 return mul;
    23 }
    24 void main()
    25 {
    26 int n;
    27 for(int m=1;m<25;m++)
    28 {
    29 n=m;
    30 if((n*(n+1))%4!=0)
    31 cout<<n<<" 0"<<endl;
    32 else
    33 {
    34 int sum=0;//符合要求的个数
    35 vector<record> v;
    36
    37 record r1(0,1);//n=1的情况
    38 record r2(1,0);
    39 v.push_back(r1);
    40 v.push_back(r2);
    41
    42 for (int i=2;i<=n;i++)
    43 {//计算到n的所有情况
    44 int * trip=new int[i];
    45
    46 int sum_i=power(2,i);
    47 for (int j=0;j<sum_i;j++)
    48 {//第j种分布
    49 for (int k=0;k<i;k++)
    50 {
    51 trip[k]=0;
    52 }
    53 int temp1=j,temp2=i;
    54 int x=0,y=0;//记录+,-的个数
    55 while (temp1)
    56 {
    57 if(temp1%2==0)
    58 {
    59 trip[--temp2]=0;
    60 y++;
    61 }
    62 else
    63 {
    64 trip[--temp2]=1;
    65 x++;
    66 }
    67 temp1/=2;
    68 }
    69 for (k=0;k<temp2;k++)
    70 {
    71 y++;
    72 }
    73
    74 int index=0;
    75 for (k=0;k<i-1;k++)
    76 {
    77 if(trip[k]+trip[k+1]==1)
    78 {
    79 index=index<<1;
    80 index++;
    81 }
    82 else
    83 {
    84 index=index<<1;
    85 }
    86 }
    87
    88 x=x+v[2*(power(2,i-2)-1)+index].pos_num;
    89 y=y+v[2*(power(2,i-2)-1)+index].neg_num;
    90
    91 record r(x,y);//存储第j种分布
    92 v.push_back(r);
    93 }
    94
    95 }
    96 int base=2*(power(2,n-1)-1);
    97 int base_n=power(2,n);
    98 for (i=0;i<base_n;i++)
    99 {
    100 if(v[base+i].pos_num==v[base+i].neg_num)
    101 sum++;
    102 }
    103 cout<<n<<" "<<sum<<endl;
    104 }
    105 }
    106 }

    题中,n<=24,时间空间均有限制,我们可以先求出所有结果,然后保存到数组直接取来输出。这是ACM题中很常见的情况。

    提交的代码为:

    1 #include <iostream>
    2 #include <vector>
    3 using namespace std;
    4
    5 long result[24]={0,0,4,6,0,0,12,40,0,0,171,410,0,0,1896,5160,0,0,32757,59984,0,0,431095,822229};
    6 void main()
    7 {
    8 int n;
    9 cin>>n;
    10 while(n!=0)
    11 {
    12 cout<<n<<" "<<result[n-1]<<endl;
    13 cin>>n;
    14 }
    15 }
  • 相关阅读:
    MYSQL 日志参数与性能的关系
    mybatis 中 foreach collection的三种用法
    SqlServer查找引用存储过程的地方_字段在哪些表中
    ubuntu中sudo不用输入密码配置
    matlab练习程序(罗德里格斯变换)
    matlab练习程序(多边形扩展算法)
    matlab练习程序(生成gif图片)
    python3 mac环境 生成pdf
    requests 爬取 台州市 履行中状态的合同附件
    个人支付方案(免签约)-支付宝当面付
  • 原文地址:https://www.cnblogs.com/njucslzh/p/1726050.html
Copyright © 2011-2022 走看看