NYOJ491幸运三角形

幸运三角形

时间限制:1000 ms  |  内存限制:65535 KB

难度:3

描述

话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒置的金字塔形状,除第一层外(第一层为所有可能情况),每层形状都由上层决定,相邻的符号相同,则下层的符号为‘+’,反之,为‘-’;如下图所示(n = 3 时的两种情况):

如果图中的两种符号个数相同,那这个三角形就是幸运三角形,如上图中的图(2).

输入
有多组测试数据(少于20组)。
每行含一个整数n(0<n<20)。
输出
输出相应的幸运三角形个数。
样例输入
3
4
样例输出
4
6
/*#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n, cnt;
int a[25];
int check()//每次总是觉得这个check函数是最难得
{
    int i, j, t1, t0;
    t1 = 0;
    t0 = 0;
    for(j = n - 1; j >= 0; j--)//外层循环是有几层,即循环的n次
    {
        for(i = 0; i <= j; i++)//里层循环式一层有几个字符,即有j个
        {
            if(a[i] == 1)//计数是+还是-
                t1++;
            else
                t0++;
            if(i > 0)//因为是用的一维数组存的,所以这里的主要作用是把这个一维数组变成下一层所需要的样式
            {
                if(a[i] == a[i - 1])//符号相同则是+
                    a[i - 1] = 1;
                else//否则是-
                    a[i - 1] = 0;
            }
        }
    }
    if(t1 == t0)
        return 1;
    return 0;
}
void dfs(int x)
{
    if(x == n)
    {
        if(check() == 1)
            cnt++;
        return ;//开始把return放在if里面了一直出不来结果,真是笨笨的脑袋
    }
    a[x] = 1;//这里并没有往常一样有if判断了,而是直接深搜了
    dfs(x + 1);
    a[x] = 0;//这里回溯回来的时候继续深搜下去,思路还是比较清晰的
    dfs(x + 1);
}
int main()
{
    while(scanf("%d", &n) != EOF)
    {
        cnt = 0;
        dfs(0);
        printf("%d\n", cnt);
    }
    return 0;
}
*/  打表
#include <stdio.h>
int a[21] = {0,0,0,4,6,0,0,12,40,0,0,171,410,0,0,1896,5160,0,0,32757};//打表最好不要用for循环
int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        printf("%d\n", a[n]);
    }
    return 0;
}

  OJ平台最优代码:

#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)
       {
            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()
{
    freopen("input.txt","r",stdin);
    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;
}

  程序用一个t表示第一行中n个数中的第几个数,用第一重循环来赋值n个数的0或1值。然后再用一重循环,不断去更新每行未更新的。因为t不断加1,j每次都是从2开始,所以当t增大,当到j行时,明显j每次只是重复2-t之中,所以这样就实现了当第一行每增加一个数,都能补全为一个三角形了。

时间: 2024-08-11 03:36:04

NYOJ491幸运三角形的相关文章

HDU 2510 符号三角形 NYOJ491 幸运三角形

符号三角形 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 860    Accepted Submission(s): 437 Problem Description 符号三角形的 第1行有n个由"+"和"-"组成的符号 ,以后每行符号比上行少1个,2个同号下面是"+",2个异 号下面

NYOJ-491 幸运三角形

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

搜索---幸运三角形

//一. #include<iostream> #include<cstring> using namespace std; int main(){ int n,ans[22]; memset(ans,0,sizeof(ans));// ans[3]=4;ans[4]=6;ans[7]=12;ans[8]=40;ans[11]=171;ans[12]=410;  ans[15] = 1896;ans[16]=5160;ans[19]=32757;ans[20]=59984; whi

nyoj 491 幸运三角形 【DFS】+【打表】

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

nyoj 491 幸运三角形 (dfs + 打表 出现木马 哈哈)

题目491 题目信息 运行结果 本题排行 讨论区 幸运三角形 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 话说有这么一个图形,只有两种符号组成('+'或者'-'),图形的最上层有n个符号,往下个数依次减一,形成倒置的金字塔形状,除第一层外(第一层为所有可能情况),每层形状都由上层决定,相邻的符号相同,则下层的符号为'+',反之,为'-';如下图所示(n = 3 时的两种情况): 如果图中的两种符号个数相同,那这个三角形就是幸运三角形,如上图中的图(2). 输入

幸运抽奖,分解一个千位数求各位数之和

import java.util.Scanner; /** * @author 蓝色以太 * 幸运抽奖 */ public class LuckyDraw { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("请输入4位会员卡号:"); int num=sc.nextInt(); int ge=num%10; int shi=num%100/10

bzoj4568 [Scoi2016]幸运数字

Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一些旅行者希望游览 A 国.旅行者计划乘飞机降落在 x 号城市,沿着 x 号城市到 y 号城市之间那条唯一的路径游览,最终从 y 城市起飞离开 A 国.在经过每一座城市时,游览者就会有机会与这座城市的幸运数字拍照,从而将这份幸运保存到自己身上.然而,幸运是不能简单叠加的,这一点游览者也十分清楚.他们迷

bzoj 4568: [Scoi2016]幸运数字

4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 848  Solved: 336[Submit][Status][Discuss] Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一些旅行者希望游览 A 国.旅行者计划 乘飞机降落在 x 号城市,沿着 x 号

【bzoj1853】 Scoi2010—幸运数字

http://www.lydsy.com/JudgeOnline/problem.php?id=1853 (题目链接) 今天考试考了容斥,结果空知道结论却不会写= = 题意:求区间中不含6,8两个数字及由6,8组成的数字的倍数的的数有几个 Solution  容斥原理.  先把所有的幸运数字都蒯到一个数组里,将两两之间可以整除的数只留下一个小的.  接下来如果暴力组合统计答案的话肯定会TLE,因为就算去掉了可以被整除的数以后还是有1000多个幸运数组.我们考虑dfs,x记录当前已经枚举到了第几个