09年山东大学计算机上级题目和我的代码
题目是从网上看到的,我花了点时间做了一下。可惜不能上传附件,只能贴代码了
一共两个题,每个50分,上机环境不限,编程语言不限,只要求结果,不要源代码,数据随机生成。题目均非准确描述,但保持了原意
【1】输入一个整数,它可以由n(n>=2)个连续整数相加得到,输出所有可能的连续整数序列,每个序列占一行,数字之间用空格分开,数据从小到大,每列按最小元素递增顺序排列,如果找不到,输出none例:21=1+2+3+4+5+6
21=6+7+8则输出1 2 3 4 5 6
6 7 8【2】某国设计了一种导弹防御系统,但有缺陷,导弹来袭时,第一枚炮弹可以达到任意高度,但以后的任意一炮均不能超过前一发炮弹高度。现在仅有一套这样的系统
输入:来袭的导弹数目(不超过100枚)输出:1:能够拦截的导弹数目30分2:若要拦截所有导弹,需要几套这样的系统20分
其实第一问就是找一个递减序列的长度,第二问就是找一下有几个这样的递减序列。
第一题:
#include
#include
using namespace std;
//使用算法,搜索
int n; //输入
int copyN; //保存n的一个副本
int length; //纪录从start开始的长度,例如1,2,3,4,5,length则为5
int yes; //标记
void initialize() {
yes = 0;
length = 0;
}
void DFS( int start ) { //从start开始,start+1, start+2,...
if( n == 0 ) { //说明n成功分解
yes = 1;
}
else {
if( n >= start ) { //说明还可以继续
n -= start;
length++;
DFS( start + 1 );
}
else { //说明n分解失败
return;
}
}
}
void print( int i ) {//输出i,i+1, i+2,...
int j;
for( j = 0; j < length; j++ ) {
cout << i + j << ' ';
}
cout << endl;
}
int main() {
cin >> n;
while( n > 0 ) {
int i;
for( i = 1; i <= n / 2; i++ ) { //对第一个数进行试探
initialize();
copyN = n;
DFS( i ); //从i开始一直往下数
if( yes == 1 ) {
print( i );
}
n = copyN;
}
cin >> n;
}
return 0;
}
第二题:
#include
#include
using namespace std;
//使用算法,动态规划,典型算法是求最长递增子序列,此题是求最长递减子序列,
//算法如下: m为以a结尾的最长递减子序列的长度,例如数组a为9 10 5 6 4 1 3
// 那么m[5]为4,最长递减子序列为9 5 4 1,最长递减子序列不一定是唯一的
//m= max{ m[k](若a> a[k]),m[k] + 1(若a<= a[k]) } 0 <= k < i
int a[100]; // 输入的导弹的高度
int n; // 导弹的个数
int m[100];
void initialize() {
//初始化m,最长递减子序列的长度至少是1
int i;
for( i = 0; i < n; i++ ) {
m= 1;
}
}
void print() {
int i;
for( i = 0; i < n; i++ ) {
cout << m<< ' ';
}
cout << endl;
}
int main() {
cin >> n;
int i, k;
for( i = 0; i < n; i++ ) {
cin >> a;
}
initialize();
//与上面的动态规划算法一致
for( i = 1; i < n; i++ ) {
for( k = 0; k < i; k++ ) {
if( a> a[k] ) {
if( m[k] > m) {
m= m[k];
}
}
else {
if( m[k] + 1 > m) {
m= m[k] + 1;
}
}
}
}
//解第一问,能够最多拦截的导弹数目
int largest = m[0];
for( i = 1; i < n; i++ ) {
if( m> largest ) {
largest = m;
}
}
cout << largest << endl;
//第二问没有那么简单,不能直接用上面的结果,考虑下面这个例子
//a 为 9 5 10 6 4 1, 最长递减子序列的长度为4,
//方案一, 第一次去掉 9 5 4 1,第二次去掉 10 6
//方案二, 第一次去掉 9 6 4 1,第二次去掉 5, 第三次去掉10
//可以看到,需要系统的个数与最长子序列的选择有关,必须选出一个好的
//最长子序列,以达到最优,谁能做出来?
system( "pause" );
}