zoukankan      html  css  js  c++  java
  • poj 3187 Backward Digit Sums

    Backward Digit Sums
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 5389   Accepted: 3112

    Description

    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: 

        3   1   2   4
    
          4   3   6
    
            7   9
    
             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.

    Input

    Line 1: Two space-separated integers: N and the final sum.

    Output

    Line 1: An ordering of the integers 1..N that leads to the given sum. If there are multiple solutions, choose the one that is lexicographically least, i.e., that puts smaller numbers first.

    Sample Input

    4 16

    Sample Output

    3 1 2 4

    Hint

    Explanation of the sample: 

    There are other possible sequences, such as 3 2 1 4, but 3 1 2 4 is the lexicographically smallest.

    Source


    起初毫无思路,,后来慢慢想出了DFS,,有两个很关键的地方,,一个是由最底层求出最顶的一个数的时候,,是需要用到
    杨辉三角的思想的,,第二点,,也非常非常重要!!要按最小字典序输出,,其实只要从小到大枚举,,一旦找到符合条件的
    退出就可以了,,这点非常关键,,不然再写个字典序函数会增加许多难度的,,p[I]表示第i位所放置的数字,,后来学习一下
    STL内部的一个全排列函数,,自己多想多想。。。。  
    解法1:暴力搜索,注意一旦找到解立即退出,,204ms
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,sum,a[12][12],p[12],flag;
    int yang()
    {
        a[1][0]=n;
        for(int i=1;i<=n;i++)
             a[1][i]=p[i];
        for(int i=2;i<=n;i++)
        {
            for(int j=1;j<=a[i-1][0]-1;j++)
             a[i][j]=a[i-1][j]+a[i-1][j+1];
            a[i][0]=a[i-1][0]-1;
        }
        return a[n][1];
    }
    int dfs(int cur)
    {
          if(!flag)
             return 0;
          if(cur==n+1)
         {
            int toa=yang();
            if(toa==sum)
            {
                flag=0;
                 printf("%d",p[1]);
             for(int i=2;i<=n;i++)
                printf(" %d",p[i]);
             printf(" ");
            }
            return 0;
         }
         for(int i=1;i<=n;i++)
            {
            int ok=1;
            for(int j=1;j<cur;j++)
                 if(p[j]==i)
            {
                ok=0;
                break;
            }
               if(ok)
               {
                 p[cur]=i;
                 dfs(cur+1);
                 p[cur]=-1;
               }
            }
         return 0;
    }
    int main()
    {
        while(~scanf("%d %d",&n,&sum))
        {
             flag=1;
             memset(p,0,sizeof(p));
             dfs(1);
        }
        return 0;
    }


    解法二:STLnext_permutation函数调用+优化后的杨辉三角   79ms
    需要注意的是next_permutation()函数是求出当前字典序的下一个,,所以
    while(next_permutation(a+1,a+n+1));不能写在开头,,,因为next_permutation(a+1,a+n+1))函数只有在当前字典序是最大时才会
    返回false,,所以放在开头的话已经进行了一次排序了,所以从1--n这个字典序直接会被跳过
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int main()
    {
        int n,sum;
        while(~scanf("%d %d",&n,&sum))
        {
           int a[13],b[13];
           for(int i=1;i<=n;i++)
               a[i]=i;
           do{
                for(int j=1;j<=n;j++)
                      b[j]=a[j];
               int temp=n;
               while(temp>1)
               {
                    for(int j=1;j<=temp-1;j++)
                        b[j]+=b[j+1];
                    temp--;
               }//杨辉三角优化

                if(b[1]==sum)
                {
                     for(int i=1;i<=n-1;i++)
                        printf("%d ",a[i]);
                     printf("%d ",a[n]);
                     break;
                }
           }while(next_permutation(a+1,a+n+1));
        }
        return 0;
    }
  • 相关阅读:
    jQuery cookie记住用户名密码自动登录
    MySQL解决8小时内没有进行数据库操作, mysql自动断开连接, 需要重启tomcat的问题
    JavaWeb项目设置Session失效时长,失效后自动跳转页面
    JS通过id获取表格内容,并循环添加到数据库
    JS实现表格Table动态添加删除行
    使用easyUI框架实现select下拉框动态加载option
    MySQL数据库出现Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ...this is incompatible with sql_mode=only_full_group_by的问题
    JS获取系统当前时间
    同一机器不同数据库间关联查询
    Fiddler各模块使用说明
  • 原文地址:https://www.cnblogs.com/smilesundream/p/6642556.html
Copyright © 2011-2022 走看看