上机练习二
导航:复试上机历年真题,题目未搜集全
十四:2003 十三:2004
十二:2005 十一:2006
十:2007 九:2008
八:2009 七:2012
六:2013 五:2014
四:2015 三:2017
二:2018 一:2019
二、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;
}
汇总链接
posted on 2020-04-13 17:39 weilanhanf 阅读(783) 评论(0) 编辑 收藏 举报