北师大ACM新手指导第十四题-灵活运用枚举

来源:互联网 发布:mac口红推荐色号 编辑:程序博客网 时间:2024/04/30 17:22
北师大ACM新手指导第十四题-灵活运用枚举Time Limit: 1000msMemory Limit: 65536KB64-bit integer IO format: %lld      Java class name: Main    前面我们用两道题介绍了枚举,并且给大家提供了一些递归枚举的模版。然后,大家尝试用该模版完成了"全排列"这道题。 而且,有些同学并没有采用我提供的模版,也解决了全排列的问题,这一点很值得大家学习。 不过,真实的ACM题一般都不能很简单的枚举,需要在枚举的时候加入适当的优化技巧,否则程序的运行时间将超过1秒钟。 而且,我给大家提供的模版,是因为那个模版有一定的通用性和可扩充性,可以根据题目的变化,适当进行非常小量的修改,即可完成新的题目。 所以希望大家还是能够把我的模版也看懂。 下面让我们用枚举来完成这道真实的ACM题,此题为2003年在广州举行的ACM亚洲区比赛的题目,如果能够在55分钟内完成此题(加上罚时),则可以获得当年广州赛区的铜奖: John von Neumann, b. Dec. 28, 1903, d. Feb. 8, 1957, was a Hungarian-American mathematician who made important contributions to the foundations of mathematics, logic, quantum physics, meteorology, science, computers, and game theory. He was noted for a phenomenal memory and the speed with which he absorbed ideas and solved problems. In 1925 he received a B.S. diploma in chemical engineering  from Zurich Institute and in 1926 a Ph.D. in mathematics from the University of Budapest. His Ph.D. dissertation on set theory was an important contribution to the subject. At the age of 20, von Neumann proposed a new definition of ordinal numbers that was universally adopted. While still in his twenties, he made many contributions in both pure and applied mathematics that established him as a mathematician of unusual depth. His Mathematical Foundations of Quantum Mechanics (1932) built a solid framework for the new scientific discipline. During this time he also proved the mini-max theorem of GAME THEORY. He gradually expanded his work in game theory, and with coauthor Oskar Morgenstern he wrote Theory of Games and Economic Behavior (1944).There are some numbers which can be expressed by the sum of factorials. For example 9, 9 = 1! + 2! + 3! Dr. von Neumann was very interested in such numbers. So, he gives you a number n, and wants you to tell him whether or not the number can be expressed by the sum of some factorials.Well, it's just a piece of cake. For a given n, you'll check if there are some xi, and let n equal to SUM{xi!} (1 ≤ i ≤ t, t ≥ 1, xi ≥ 0, xi = xj iff. i = j). If the answer is yes, say "YES"; otherwise, print out "NO".InputYou will get several non-negative integer n (n ≤ 1,000,000) from input. Each one is in a line by itself. The input is terminated by a line with a negative integer.OutputFor each n, you should print exactly one word ("YES" or "NO") in a single line. No extra spaces are allowed.Sample Input123459-1Sample OutputYESYESYESYESNOYES------------------------------------------------------------------------------------------------------
//.............#include <cstdio>#include <iostream>using namespace std;int n,flag,A[10]={1};//在 1! ~ 9! 之间void DFS(int value,int Set){    if(Set<0||value>n) return;    if(value==n) {flag=1;return;}    DFS(value+A[Set-1],Set-1);    DFS(value,Set-1); //不加下一个 留着给后面加}int main(void){    for(int i=1;i<=9;i++) A[i]=i*A[i-1]; //阶乘表    while(cin>>n)    {        if(n<0) break;        flag=0;DFS(0,10);        printf("%s\n",n!=0&&flag?"YES":"NO");    }}

/*!这个思路非常简单 如果是a!+b!+c! 那么从后往前面减
1! < 2!
1!+2!< 3!
1!+2!+3! < 4!
……………
1!+2!+3!+n! < (n+1)!=(n+1)*n!
——->那么只是从中抽取的元素阶乘和就更小于n!
——->若S=a!+b!+c!+..+j!+k! ,a

#include<iostream>using namespace std;int n,A[10]={1};int main(){    for(int i=1;i<=9;i++) A[i]=i*A[i-1]; //阶乘表    while(cin>>n&&n>=0)    {        if(n==0){cout<<"NO"<<endl;continue;}        for(int i=9;i>=0&&n;i--) if(A[i]<=n) n-=A[i];        n==0?cout<<"YES"<<endl:cout<<"NO"<<endl;    }    return 0;}来源: https://www.bnuoj.com/bnuoj/status.php
0 0
原创粉丝点击