返回顶部

上机练习九

导航:复试上机历年真题,题目未搜集全
十四:2003 十三:2004
十二:2005 十一:2006
十:2007 九:2008
八:2009 七:2012
六:2013 五:2014
四:2015 三:2017
二:2018 一:2019

github汇总链接

九、2008

1、相约2008

题目:
相约 2008:2008 是一个合数,求出此合数最多由多少个最小不同质数和组成,并按要求从小到大输出这些质数。
思路:
我觉得这是这几年题目最难的一道,这个题目跟17年的求连续素数的和等于某一值不一样,如果为了满足最多的最小质数和,则需要从右往左遍历贪心求连续的素数和,到最后会发现,无法求得一个方案,结果差1,而如果将1当做最小的素数,填补这个差值,恰好可以满足条件。但是显然1不是素数。

没有想到求满足最小的质数和,但是可以求出来一种方案。

  • 首先先素数打表
  • 用动态规划求从数组中取出几个数满足某一个和S
  • 再根据条件找出这几个数

动态规划的过程就是给定一个正整数s, 判断一个数组arr中,是否有一组数字加起来等于s。可以参考传送门:动态规划

代码:

#include<stdio.h>
#include<algorithm>

using namespace std;

const int maxn=2009;

int num=0;
int p[maxn], prime[maxn];//prime数组用来存放素数 




void primeTable()//素数表 
{
	for(int i=2;i<maxn;i++)
	{
		if(p[i]==0)//p[i]=0说明i是素数 
		{
			prime[num++] = i;//i是素数放入prime数组 
			for(int j=2*i;j<maxn;j+=i) 
			{
				p[j] = 1;//i为素数,则i的倍数都不是素数 
			}
		}
	}
}



void dpCreat(int arr[], int n, int S)
{
	int dp[n][S+1]={0};
	
	//边界条件 
	for(int i=0;i<n;i++)
		dp[i][0] = 0;
	for(int j=0;j<S+1;j++)
		dp[0][j] = 0;
	dp[0][arr[0]] = 1;
	
	//状态方程 
	for(int i=1;i<n;i++)
		for(int j=1;j<S+1;j++)
		{
			if(arr[i]>j)
				dp[i][j] = dp[i-1][j];
			else if(arr[i]<=j)//选与不选arr[i]只需要满足其一就可 
			{
				int a=dp[i-1][j];
				int b=dp[i-1][j-arr[i]];
				dp[i][j] = a||b;
			}	
		} 
	

	//查找方案 
	if(dp[n-1][S]==1)
	{
		printf("存在方案:\n");
	
		int i = n-1, k=0;
		int sol[maxn] = {0};
		while(i>=0)
		{
			if((dp[i][S]==1)&&(dp[i-1][S]==0))
			{
				sol[k++] = arr[i];
				S -= arr[i];
			}
			if(S==0)
				break;
		 	i--;
		}
		int sums = 0;
		for(int j=0;j<k;j++)
		{
			sums += sol[j];
			printf("%4d ", sol[j]);
		}
	}
	else
		printf("不存在\n"); 
		
}



int main()
{
	int S=2008;
	primeTable();
	
	int sums=0, n=0;
	for(int i=0;i<num;i++)
	{
		sums += prime[i]; 
		n++;
		if(sums>=S)
			break;
	}
	
	dpCreat(prime, n, S);
	
	return 0;
}


2、二叉树

题目:
从键盘接受输入,每个节点所含数据元素均为单字符,要完成:建立一棵二叉链表表示方式存储的二叉排序树,并打印输出对其由大到小遍历结果。测试数据:输入 EFHJBCAGID,符号“@”表示结束字符

思路:
二叉排序树的建立,如果要找到一个从大到小遍历的结果,可以先用中序遍历结果存放在一个栈中,然后再逐个弹栈顶元素。或者直接逆中序遍历即可。

代码:

#include<stdio.h>
#include<stack>

using namespace std;

typedef struct BSTNode
{
	char data;
	struct BSTNode *lchild, *rchild;
}BSTNode, *BSTree;


stack<char> st;


void insert(BSTree *bst, char ch)
{
	if(*bst==NULL)
	{
		BSTNode *q;
		q = new BSTNode;
		q->lchild = NULL; q->rchild = NULL;
		q->data = ch;
		*bst = q;
	}
	else
	{
		if(ch>(*bst)->data)
			insert(&((*bst)->rchild), ch);
		else if(ch<(*bst)->data)
			insert(&((*bst)->lchild), ch);
	}
}


void creatBST(BSTree *bst)//创建二叉排序树 
{
	char ch;
	*bst = NULL; 
	scanf("%c", &ch);
	while(ch!='@')
	{
		insert(bst, ch);
		scanf("%c", &ch);
	}
}


void inTravel(BSTree bst)//放在栈中 
{
	if(bst!=NULL)
	{
		inTravel(bst->lchild);
		st.push(bst->data);
//		printf("%c", bst->data);
		inTravel(bst->rchild);
	}
}


void reverseTravel(BSTree bst)//直接逆序输出 
{
	if(bst!=NULL)
	{
		reverseTravel(bst->rchild);
		printf("%c", bst->data);
		reverseTravel(bst->lchild);	
	}	
} 


int main()
{
	BSTree bst;
	bst = new BSTNode;
	creatBST(&bst);
	inTravel(bst);
	
	while(st.empty()==false)//逐个弹出栈顶元素 
	{
		printf("%c", st.top());
		st.pop();
	}
	
	printf("\n");
	reverseTravel(bst);
	
	return 0;
}

3、字符平台

题目:
编写程序:求字符串中的最大字符平台。
一个字符串中的任意一个子序列,若子序列中各字符均相同则被称为字符平台。编程要求:输入任意一字符串 S 时,输出 S 中长度最大的所有字符平台的起始位置以及所含字符,注意字符平台有可能不止一个

代码:

#include<stdio.h>
#include<string.h>

using namespace std;


typedef struct plat{
	char ch;
	int pos;
	int n;
	plat()
	{
		pos=0;
		n=0;
	}
}plat;


plat p[100];
int num=0;


int main()
{
	char str[100];
	int len;
	gets(str);
	len = strlen(str);
	
	for(int i=0;i<len;i++)
	{
		if(i==0)//第一个字符必当占一个字符平台 
		{
			p[num].ch = str[i];
			p[num].pos = i;
			p[num].n++;
		}
		else//要判断连续的字符是否相同, 
		{
			if(str[i]==str[i-1])//如果相同字符平台长度加1
			{
				p[num].n++;	
			}	
			else//不相同新增一个字符平台
			{
				num++;
				p[num].ch = str[i];
				p[num].pos = i;
				p[num].n++;	
			}
		}
	}
	
	int k=0;
	for(int i=0;i<=num;i++)//找出最大的字符平台的长度 
		if(p[i].n>k)
			k=p[i].n;
	
	
	for(int i=0;i<=num;i++)
		if(p[i].n==k)
			printf("%c %d %d\n", p[i].ch, p[i].pos, p[i].n);
	
	return 0;
}

汇总链接

github汇总链接

posted on 2020-04-17 20:24  weilanhanf  阅读(538)  评论(0编辑  收藏  举报

导航