• 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;
    }
  • 相关阅读:
    POJ 2752 Seek the Name, Seek the Fame
    POJ 2406 Power Strings
    对闭包的理解(closure)
    HDU
    Python字典遍历的几种方法
    面向对象的六大原则
    Android添加代码检查权限
    Android请求网络权限
    android广播接收器BroadcastReceiver
    Android中SQLite下 Cursor的使用。
  • 原文地址:https://www.cnblogs.com/smilesundream/p/6642556.html
Copyright © 2020-2023  润新知