描述

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

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

输入
有多组测试数据(少于20组)。
每行含一个整数n(0<n<20)。
输出
输出相应的幸运三角形个数。
样例输入
3
4
样例输出
4
6
///排列组合第一行,然后直接寻找是否相等
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 1010
#define MOD 1000000007
using namespace std;
int n,m,ans[];
int a[];///待排列的数存储在此
bool vis[];
int p[N][N],k;
int sum,num,tot;
void dfs(int cnt)///按字典序输出n个数选m个数的所有排列
{
if(cnt==m)
{
for(int i=; i<m; i++)
{
if(ans[i] == ans[i+] && i+ < m)
p[][k] = ,sum++;
else
p[][k] = ;
k++;
if(ans[i] == )
sum++;
}
int c = ;
while(c < m)
{
k = ;
for(int i = ; i < m - c + ; i++)
{
if(p[c-][i] == p[c-][i+] && i+ < m - c + )
p[c][k] = ,sum++;
else
p[c][k] = ;
k++;
}
c++;
}
if(sum == num)
tot++;
k = ;
// for(int i=0; i<m; i++)
// cout<<ans[i]<<"***";
// cout<<endl;
// for(int i = 1; i < m; i++)
// {
// for(int j = 0 ; j < m-i; j++)
// cout<<p[i][j]<<"***";
// cout<<endl;
// }
// cout<<sum<<" "<<num<<endl;
sum = ;
return ;
}
for(int i=; i<n; i++)
{
ans[cnt]=a[i];
dfs(cnt+);
}
}
int main()
{
while(cin>>m)
{
k = ;
n = ;
sum = ;
tot = ;
num = m * (m + );
if(num % )
{
cout<<<<endl;
continue;
}
else
num /= ;
fill(vis,vis+,);
a[] = ;
a[] = ;
dfs();
cout<<tot<<endl;
}
return ;
}

TLE

纯粹dfs,回溯还未入门,不过如果应试的话完全可以打表,毕竟数据量不是太大。

///排列组合第一行,然后直接寻找是否相等
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 1010
#define MOD 1000000007
using namespace std;
int n,m,ans[];
int a[];///待排列的数存储在此
bool vis[];
int p[N][N],k;
int sum,num,tot;
void dfs(int cnt)///按字典序输出n个数选m个数的所有排列
{
if(cnt==m)
{
for(int i=; i<m; i++)
{
if(ans[i] == ans[i+] && i+ < m)
p[][k] = ,sum++;
else
p[][k] = ;
k++;
if(ans[i] == )
sum++;
}
int c = ;
while(c < m)
{
k = ;
for(int i = ; i < m - c + ; i++)
{
if(p[c-][i] == p[c-][i+] && i+ < m - c + )
p[c][k] = ,sum++;
else
p[c][k] = ;
k++;
}
c++;
}
if(sum == num)
tot++;
k = ;
// for(int i=0; i<m; i++)
// cout<<ans[i]<<"***";
// cout<<endl;
// for(int i = 1; i < m; i++)
// {
// for(int j = 0 ; j < m-i; j++)
// cout<<p[i][j]<<"***";
// cout<<endl;
// }
// cout<<sum<<" "<<num<<endl;
sum = ;
return ;
}
for(int i=; i<n; i++)
{
ans[cnt]=a[i];
dfs(cnt+);
}
}
int main()
{
for(m = ; m < ; m++)
//while(cin>>m)
{
k = ;
n = ;
sum = ;
tot = ;
num = m * (m + );
if(num % )
{
cout<<<<",";
continue;
}
else
num /= ;
fill(vis,vis+,);
a[] = ;
a[] = ;
dfs();
cout<<tot<<",";
}
return ;
}

打表过了

回溯才是正解,可以减掉重复计算的值,但是自己没搞懂,留下正解先

///边回溯边计算,避免重复计算
#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=; i<; ++i) //只取 0('+') 或者 1('-')
{
p[][t] = i; //第一行第 t个符号
counter += i; //'-'号统计
for(j=; j<=t; ++j) //当第一行符号 >=2时,可以运算出下面行的某些符号(第一行有几个数就可以相应往下计算几行,每次计算过的就不用重复计算)
{
p[j][t-j+] = p[j-][t-j+]^p[j-][t-j+];//通过异或运算下行符号
counter += p[j][t-j+];
}
if( (counter <= half) && ( t*(t+)/ - counter <= half) )//若符号统计未超过半数,并且另一种符号也未超过半数
Backtrace(t+); //在第一行增加下一个符号
//回溯,判断另一种符号情况
for(j=; j<=t; ++j)
counter -= p[j][t-j+];
counter -= i;
}
}
} int main()
{
while(scanf("%d", &n) != EOF)
{
counter = ;
sum = ;
half = n*(n+)/; if( half% == )//总数须为偶数,若为奇数则无解
{
half /= ;
p = new char *[n+];
for(int i=; i<=n; ++i)
{
p[i] = new char[n+];
memset(p[i], , sizeof(char)*(n+));
}
Backtrace();
}
printf("%d\n", sum);
}
return ;
}

回溯正解

http://www.cnblogs.com/dongsheng/archive/2013/06/16/3138607.html

NYOJY 491 幸运三角形的更多相关文章

  1. NYOJ 491 幸运三角形

    幸运三角形 import java.util.Scanner; public class Main{//搜索 static int sum=0,n; public static void main(S ...

  2. nyoj 幸运三角形

    幸运三角形 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒 ...

  3. 幸运三角形 南阳acm491(dfs)

    幸运三角形 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 话说有这么一个图形,只有两种符号组成(‘+’或者‘-’),图形的最上层有n个符号,往下个数依次减一,形成倒 ...

  4. NYOJ--491--dfs(打表水过)--幸运三角形

    /* Name: NYOJ--491--幸运三角形 Author: shen_渊 Date: 15/04/17 16:26 Description: DFS超时,深搜出第一行的所有情况,计算之后打表水 ...

  5. nyoj--491--幸运三角形(dfs)

    幸运三角形 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 话说有这么一个图形,只有两种符号组成('+'或者'-'),图形的最上层有n个符号,往下个数依次减一,形成倒置的 ...

  6. 用CSS绘制箭头等三角形图案 [译]

    最近重新设计了我的网站,准备添加tooltips提示信息效果.实现很容易,但我想要让提示功能具有三角形的指示图标.当我重新思考想要所设计的每个图标颜色都随心所欲的时候,采用图片那就是一场灾难.幸运的是 ...

  7. LearnOpenGL 你好,三角形[转]--附源码

    原地址:你好,三角形 你好,三角形 原文 Hello Triangle 作者 JoeyDeVries 翻译 Django 校对 Geequlim 译注 在学习此节之前,建议将这三个单词先记下来: 顶点 ...

  8. OpenGL学习笔记(二)画三角形

    目录 渲染管线(Graphics Pipeline) 编码实现 顶点数据 顶点缓冲对象(VBO) 顶点着色器 编译着色器 片段着色器 着色器程序 链接顶点属性 顶点数组对象 最终绘制三角形 索引缓冲对 ...

  9. canvas快速绘制圆形、三角形、矩形、多边形

    想看前面整理的canvas常用API的同学可以点下面: canvas学习之API整理笔记(一) canvas学习之API整理笔记(二) 本系列文章涉及的所有代码都将上传至:项目代码github地址,喜 ...

随机推荐

  1. 设计模式学习笔记-Adapter模式

    Adapter模式,就是适配器模式,使两个原本没有关联的类结合一起使用. 平时我们会经常碰到这样的情况,有了两个现成的类,它们之间没有什么联系,但是我们现在既想用其中一个类的方法,同时也想用另外一个类 ...

  2. php知识案列

     n个不重复的随机数生成代码 <?php //range 是将1到100 列成一个数组 $numbers = range (1,100); //shuffle 将数组顺序随即打乱 shuffle ...

  3. 【基本技能篇】>>第3篇《暗时间_指导学习的方法论——心得》

    暗时间——指导学习的方法论 ——2016年2月11日 打造自己的核心竞争力:①专业领域技能:②跨领域的技能(解决问题的能力,创新思维,判断与决策能力,表达沟通能力等等):③学习能力,持续学习和思考新知 ...

  4. Windows Phone 10如何借Windows 10的东风

    距微软发布Windows Phone 7已经四年多了,WinPhone的市场份额一直萎糜不前.去年微软收购诺基亚,如特洛伊木马般戏剧,却没有挽救WinPhone,甚至出现下滑,已经不足3%,已经基本被 ...

  5. linux操作系统基础

    计算机概述 1.计算机接收用户输入指令数据,经过cpu数据与逻辑单元运算处理后,产生或储存成有用的信息--->I/O设备+cpu+处理信息=计算机. 2.计算机五大单元:I/O单元 内存单元 c ...

  6. Redux教程2:链接React

    通过前面的教程,我们有了简单的环境,并且可以运行Redux的程序,也对 如何编写Redux示例 有了初步的印象: 掌握了 使用Redux控制状态转移 ,继而驱动 React 组件发生改变,这才是学习R ...

  7. VScode调试Python

    第一步,确保装上了PYTHON扩展 然后打开文件夹(这个东西必须打开文件夹才能进行调试,不能打开一个文件就调试) 打开文件夹后,那里显示没有配置,这时需要你按下F5 弹出选择环境,点击Python 它 ...

  8. 练习sql语句的好去处——http://www.sqlzoo.cn/

    sql语句的编写需要按照实际的例子来练习. 如果自己来做准备,需要你自己搭好数据库,建好库和表,还要填入数据,最后自己想出题目和正确答案. 不过,现在我发现了一个好去处,http://www.sqlz ...

  9. LINUX:read、array、declare

    read:要读取来自键盘输入的变量 使用规则: read [-pt] variale 选项与参数: -p:后面接提示字符: -t:后面接等待的“秒数”: 如果read之后不加任何参数,直接加上变量名称 ...

  10. linux内核学习之四 系统调用

    一  概念区分 提到linux系统调用,不得不区分几个比较容易混淆的概念: 系统调用:系统调用就是一种特殊的接口.通过这个接口,用户可以访问内核空间.系统调用规定了用户进程进入内核的具体位置. 应用程 ...