返回顶部

上机练习二

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

github汇总链接

二、2018

1、序列排序

题目:
输入一个升序序列,以 0 结束,输出该序列,统计序列中的数字个数,将指
定位置以后的数字逆序。例如,输入:2,3,4,67,89,0 输出:2,3,4,67,89,
输出个数为 5,输入 3,输出:2,3,89,67,4

代码:

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

using namespace std;


int main()
{
	int a[100];
	int n, x, num;
	num=0;
	while(scanf("%d", &x)!=EOF&&x!=0)
	{
			a[num++]=x;
	}
	
	printf("输入位置(从1开始):"); 
	scanf("%d", &n);
	
	
	reverse(a+n-1, a+num);
	for(int i=0;i<num;i++)
		printf("%d ", a[i]);
	
	return 0;
 } 

2、人民币组合问题

题目:
组合人民币问题。有面值为 100 50 20 10 5 1 的几种人民币,输入金额,罗
列出所有的组合方案,并且统计出用的张数最少的那一种,并且显示。

<1>、法一

暴力破解代码:

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

using namespace std;


int a[6] = {100, 50, 20, 10, 5, 1};


int main()
{
	int z;
	scanf("%d", &z);
	
//	for(int i=0;i<=z/100;i++)
//		for(int j=0;j<=1;j++)
//			for(int m=0;m<=2;m++)
//				for(int n=0;n<=1;n++)
//					for(int x=0;x<=1;x++)
//						for(int y=0;y<=4;y++)
//							if(i*100+j*50+m*20+n*10+x*5+y*1==z)
//								printf("%d张100元 %d张50元 %d张20元 %d张10元 %d张5元 %d张1元\n", i, j, m, n, x, y);
//	
	
	for(int i=0;i<=z/100;i++)
		for(int j=0;j<=z/50;j++)
			for(int m=0;m<=z/20;m++)
				for(int n=0;n<=z/10;n++)
					for(int x=0;x<=z/5;x++)
						for(int y=0;y<=z/1;y++)
							if(i*100+j*50+m*20+n*10+x*5+y*1==z)
								printf("%d张100元 %d张50元 %d张20元 %d张10元 %d张5元 %d张1元\n", i, j, m, n, x, y);
	
	
	
	printf("最少张数:\n");
	int k=0;
	while(z!=0)
	{
		printf("%d张%d元 ", z/a[k], a[k]);
		z %= a[k];
		k++;
	} 
	
	
	return 0; 
}

<2>、法二

动态规划求方案数:
已知的纸币面额为1,5,10,20,50,100。

情况一:
比如当输入金额n=500时,显然n>最大面值100,那么会有两种情况:使用100面额的纸币与不使用100面额的纸币

  • 使用,此时的方案数为m,m就等于金额为400,用六种纸币组合的方案数
  • 不使用,此时的方案数为n,n就等于金额为500的时候,用前5中纸币组合的方案数
    那么对于金额为500用以上纸币做组合的方案就为m+n

情况二:
比如当输入金额恰好n=100时,显然n=最大面值100,那么会有两种情况:使用100面额的纸币与不使用100面额的纸币

  • 使用,此时的方案数为1
  • 不使用,此时的方案数为n,n就等于金额为100的时候,用前5种(1,5,10,20,50)纸币组合的方案数
    那么对于金额为100用以上纸币做组合的方案就为1+n

情况三:
比如当输入金额n=80时,显然n<最大面值100,那么只有一种情况:不使用100面额的纸币,因为100的面额>80,无法使用

  • 不使用,此时的方案数为n,n就等于金额为80的时候,用前5种(1,5,10,20,50)纸币组合的方案数
    那么对于金额为80用以上纸币做组合的方案就为n

状态方程,设置方案数组dp[6][n+1]因此根据输入金额不同分为了三种情况:

  • dp[i][j] = dp[i-1][j], j<coin[i]
  • dp[i][j] = dp[i-1][j]+1, j==coin[i]
  • dp[i][j] = dp[i-1][j]+dp[i][j-coin[i]], j>coin[i]
    其中i表示数组coin下标,coin[i]则表示对应的纸币面值;j表示输入金额

初始情况,也即数组边界

  • 当输入金额n=0时候,用任何的coin数组中的纸币也无法组合,因此dp[i][0]=0;
  • 当只用面值为1的纸币组合时,对于任何的输入金额,只能有一种方案,即用1表示j,因此dp[0][j]=1;

代码:

#include<stdio.h>

const int maxn=1000;


int main()
{
	int n;
	int coin[6]={1, 5, 10, 20, 50, 100};//纸币面值 
	int dp[6][maxn]={0};//方案数组 
	
	scanf("%d", &n);//输入金额最大为1000;
	
	//边界值初始化 
	for(int i=0;i<6;i++)//当输入金额为0的时候,排列方案为0种 
		dp[i][0] = 0;
	for(int j=0;j<=n;j++)//当只能用价值为1的纸币时,方案为1种 
		dp[0][j] = 1; 
	
	//状态方程 
	for(int i=0;i<6;i++)
		for(int j=1;j<=n;j++)
		{
			if(coin[i]>j)
				dp[i][j] = dp[i-1][j];
			else if(coin[i]<j)
				dp[i][j] = dp[i-1][j] + dp[i][j-coin[i]];
			else if(coin[i]==j)
				dp[i][j] = dp[i-1][j] + 1;	
		} 
	
	//打印方案数组 
	for(int i=0;i<6;i++)
	{
		for(int j=0;j<=n;j++)
			printf("%3d ", dp[i][j]);
		printf("\n");	
	}
	
	printf("金额为%d时,组合方案为%d种\n", n, dp[5][n]);
	
	return 0;
}

3、单词个数

题目:
输入一句英语,输出该句子,统计其中单词个数,将所有单词首字母大写。
例如:输入: I am a boy. (注意有标点符号),输出:I am a boy. 输
出:4 输出:I Am A Boy.

代码:

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


bool isalpha(char ch)
{
	if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
		return true;
	return false;
}

bool islower(char ch)
{
	if(ch>='a'&&ch<='z')
		return true;
	return false;	
}


void upper(char &ch)
{
	if(ch>='a'&&ch<='z')
		ch -= 32;
}


int main()
{
	char str[100];
	gets(str);
	
	int len = strlen(str);
	int m,n;
	m=0; n=len-1;
	
	while(str[m]==' '||str[n]==' ')//去掉首尾多余空格 
	{
		if(str[m]==' ')
			m--;		
		if(str[n]==' ')
			n--;
	}		

	int count=0;
	for(int i=m;i<=n;i++)
	{
		if(i==m&&isalpha(str[i]))//首字母大写 
		{
			if(islower(str[i]))
				upper(str[i]);
			count++;
		}
		else
		{
			if(str[i]=='\'')
				count++;
			
			if(str[i-1]==' '&&isalpha(str[i]))//前一个符号为空格,下一个符号为字母,单词+1 
			{
				if(islower(str[i]))
					upper(str[i]);
				count++; 
			}
		}
		
	}
	printf("%s共有%d个单词\n", str, count);	
	
	return 0;
 } 

汇总链接

github汇总链接

posted on 2020-04-13 17:39  weilanhanf  阅读(783)  评论(0编辑  收藏  举报

导航