题目描述

FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N <= 10) in a certain order and then sum adjacent numbers to produce a new list with one fewer number. They repeat this until only a single number is left. For example, one instance of the game (when N=4) might go like this:

  1. 3 1 2 4
  2. 4 3 6
  3. 7 9
  4. 16

Behind FJ's back, the cows have started playing a more difficult game, in which they try to determine the starting sequence from only the final total and the number N. Unfortunately, the game is a bit above FJ's mental arithmetic capabilities.

Write a program to help FJ play the game and keep up with the cows.

有这么一个游戏:

写出一个1~N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置。下面是一个例子:

3 1 2 4

4 3 6

7 9 16 最后得到16这样一个数字。

现在想要倒着玩这样一个游戏,如果知道N,知道最后得到的数字的大小sum,请你求出最初序列a[i],为1~N的一个排列。若答案有多种可能,则输出字典序最小的那一个。

[color=red]管理员注:本题描述有误,这里字典序指的是1,2,3,4,5,6,7,8,9,10,11,12

而不是1,10,11,12,2,3,4,5,6,7,8,9[/color]

输入输出格式

输入格式:

两个正整数n,sum。

输出格式:

输出包括1行,为字典序最小的那个答案。

当无解的时候,请什么也不输出。(好奇葩啊)

输入输出样例

输入样例#1:

  1. 4 16
输出样例#1:

  1. 3 1 2 4

说明

对于40%的数据,n≤7;

对于80%的数据,n≤10;

对于100%的数据,n≤12,sum≤12345。

一上来,直接打的大爆搜(70)。

  1. #include<cstdio>
  2. int n,m;
  3. int s[],bf[];
  4. bool v[];
  5. void find(int x){
  6. if(x>n){
  7. s[]=n;
  8. while(s[]--){
  9. for(int i=;i<=s[];i++) s[i]+=s[i+];
  10. }
  11. if(s[]==m){
  12. for(int i=;i<=n;i++) printf("%d ",bf[i]);
  13. n=;
  14. }
  15. else{
  16. for(int i=;i<=n;i++) s[i]=bf[i];
  17. }
  18. return;
  19. }
  20. for(int i=;i<=n;i++) if(!v[i]){s[x]=bf[x]=i;v[i]=;find(x+);v[i]=;}
  21. }
  22. int main(){
  23. scanf("%d%d",&n,&m);
  24. find();
  25. return ;
  26. }

后来,看别人代码,找了一下每一位上对答案的影响。(80)

  1. #include<cstdio>
  2. int n,m;
  3. int s[],js[]={,};
  4. bool v[];
  5. void find(int x,int y){
  6. if(x>n){
  7. if(y==m){
  8. for(int i=;i<=n;i++) printf("%d ",s[i]);
  9. n=;
  10. }
  11. return;
  12. }
  13. for(int i=;i<=n;i++)
  14. if(!v[i]){
  15. s[x]=i;
  16. v[i]=;
  17. find(x+,y+js[x]*i);
  18. v[i]=;
  19. }
  20. }
  21. int main(){
  22. scanf("%d%d",&n,&m);
  23. for(int i=;i<n;i++)
  24. for(int j=i;j>;j--)
  25. js[j+]+=js[j];
  26. find(,);
  27. return ;
  28. }

最后又加了一个

  1. if(y>m) return;

的剪枝。终于过了。

代码实现:

  1. #include<cstdio>
  2. int n,m;
  3. int s[],js[]={,};
  4. bool v[];
  5. void find(int x,int y){
  6. if(y>m) return;
  7. if(x>n){
  8. if(y==m){
  9. for(int i=;i<=n;i++) printf("%d ",s[i]);
  10. n=;
  11. }
  12. return;
  13. }
  14. for(int i=;i<=n;i++)
  15. if(!v[i]){
  16. s[x]=i;
  17. v[i]=;
  18. find(x+,y+js[x]*i);
  19. v[i]=;
  20. }
  21. }
  22. int main(){
  23. scanf("%d%d",&n,&m);
  24. for(int i=;i<n;i++)
  25. for(int j=i;j>;j--)
  26. js[j+]+=js[j];
  27. find(,);
  28. return ;
  29. }

。。。我去年八月份就会的题,现在。。。

题目来源:洛谷

[USACO06FEB]数字三角形的更多相关文章

  1. P1118 [USACO06FEB]数字三角形`Backward Digit Su`… 回溯法

    有这么一个游戏: 写出一个11至NN的排列a_iai​,然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少11,直到只剩下一个数字位置.下面是一 ...

  2. P1118 [USACO06FEB]数字三角形`Backward Digit Su`…

    题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 11 to N(1 \le N \ ...

  3. P1118 [USACO06FEB]数字三角形Backward Digit Su…

    题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N ...

  4. 洛谷—— P1118 [USACO06FEB]数字三角形Backward Digit Su…

    https://www.luogu.org/problem/show?pid=1118#sub 题目描述 FJ and his cows enjoy playing a mental game. Th ...

  5. luoguP1118 [USACO06FEB]数字三角形`Backward Digit Su`… 题解

    一上午都在做有关搜索的题目,,, 看到这题之后就直接开始爆搜 结果只有70分, 其余的点硬生生的就是那么WA了. 我的天哪~ 70分代码: #include<iostream> #incl ...

  6. P1118 [USACO06FEB]数字三角形`Backward Digit Su`… (dfs)

    https://www.luogu.org/problemnew/show/P1118 看的出来是个dfs 本来打算直接从下到上一顿搜索 但是不会 看了题解才知道系数是个杨辉三角....... 这样就 ...

  7. 洛谷P1118 [USACO06FEB]数字三角形`Backward Digit Su`…

    #include<iostream> using namespace std ; ; int y[N][N]; int n; int a[N]; bool st[N]; int sum; ...

  8. Luogu P1118 [USACO06FEB]数字三角形 Backward Digit Sums | 搜索、数学

    题目链接 思路:设一开始的n个数为a1.a2.a3...an,一步一步合并就可以用a1..an表示出最后剩下来的数,不难发现其中a1..an的系数恰好就是第n层杨辉三角中的数.所以我们可以先处理出第n ...

  9. G:数字三角形

    总时间限制: 1000ms 内存限制: 65536kB描述73   88   1   02   7   4   44   5   2   6   5 (图1) 图1给出了一个数字三角形.从三角形的顶部 ...

随机推荐

  1. Net 发布网站中遇到的几点问题

    1.windows 身份验证设置 打开IIS==>=>找到网站==> 身份验证==>打开功能==>启用windows身份验证 网站设置: 博客参考: http://blo ...

  2. 365 Water and Jug Problem 水壶问题

    有两个容量分别为 x升 和 y升 的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水.你允许:    装满任 ...

  3. 290 Word Pattern 单词模式

    给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循这种模式.这里的 遵循 指完全匹配,例如在pattern里的每个字母和字符串 str 中的每个非空单词存在双向单映射关系 ...

  4. Java学习笔记-eclipse配置

    一.配置Java环境变量 JAVA_HOME:D:\Program Files\Java\jdk1.7.0_76 CLASSPATH:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HO ...

  5. C语言用指针输出数组里的值

    因为*(arr)是指arr数组内存编号所对应的首地址的值,即arr[0]的值.所以用*(arr+i)可以实现遍历整个数组.

  6. Integer / BigInteger / BigDecimal 方法

    import java.math.BigDecimal; import java.math.*; public class Main{ public static void main(String[] ...

  7. [ 东莞市选 2008 ] GCD&LCM

    \(\\\) \(Description\) 给出两数的\(GCD\)和\(LCM\),求合法的两数之差的绝对值最小是多少. \(GCD\times LCM\le10^{18}\) \(\\\) \( ...

  8. html与html5 总结

    时间:于2017年12月3日 19:35:18开始 用于: 这文章用于个人技术总结(全文转发请标明出处,小段摘抄随意) HTML笔记1.html标签不区分大小写,但是建议小写2.常用标签: 可用在he ...

  9. Typora——自定义设置

    Typora提供自定义设置,在偏好设置里面,有一个主题文件夹,如果对界面的样式进行设定,可以添加一个css文件,命名规范是 github.user.css,下面代码会对h1~h4进行自动序列化 bod ...

  10. Java代码实现WORD转PDF

    第一步: 安装OpenOffice   在此良心提供windows版本安装文件 链接:https://pan.baidu.com/s/17pPCkcS1C46VtLhevqSgPw  密码:vmlu ...