软件学院第十六次训练

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39427510/article/details/83865987

7-1 二分法求多项式单根 (20 分)

二分法求函数根的原理为:如果连续函数f(x)在区间[a,b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个根r,即f(r)=0。

二分法的步骤为:

  • 检查区间长度,如果小于给定阈值,则停止,输出区间中点(a+b)/2;否则
  • 如果f(a)f(b)<0,则计算中点的值f((a+b)/2);
  • 如果f((a+b)/2)正好为0,则(a+b)/2就是要求的根;否则
  • 如果f((a+b)/2)与f(a)同号,则说明根在区间[(a+b)/2,b],令a=(a+b)/2,重复循环;
  • 如果f((a+b)/2)与f(b)同号,则说明根在区间[a,(a+b)/2],令b=(a+b)/2,重复循环。

本题目要求编写程序,计算给定3阶多项式f(x)=a​3​​x​3​​+a​2​​x​2​​+a​1​​x+a​0​​在给定区间[a,b]内的根。

输入格式:

输入在第1行中顺序给出多项式的4个系数a​3​​、a​2​​、a​1​​、a​0​​,在第2行中顺序给出区间端点a和b。题目保证多项式在给定区间内存在唯一单根。

输出格式:

在一行中输出该多项式在该区间内的根,精确到小数点后2位。

输入样例:

3 -1 -3 1
-0.5 0.5

输出样例:

0.33
#include<cstdio>
#include<iostream>
using namespace std;
float a3,a2,a1,a0;
float f(float x){
	return a3*x*x*x+a2*x*x+a1*x+a0;
}
int main(){
	float left,right,mid;
	cin>>a3>>a2>>a1>>a0>>left>>right;
	while(left<=right-0.001&&f(right)*f(left)<=0){
		if(f(right)==0){
			printf("%.2f\n",right);
			return 0;
		}
		if(f(left)==0){
			printf("%.2f\n",left);
			return 0;
		}
		mid=(right+left)/2;
		if(f(left)*f(mid)>0){
			left=mid;
		}else{
			right=mid;
		}
	}
	printf("%.2f\n",mid);
	return 0;
}

7-2 删除字符串中的子串 (20 分)

输入2个字符串S1和S2,要求删除字符串S1中出现的所有子串S2,即结果字符串中不能包含S2。

输入格式:

输入在2行中分别给出不超过80个字符长度的、以回车结束的2个非空字符串,对应S1和S2。

输出格式:

在一行中输出删除字符串S1中出现的所有子串S2后的结果字符串。

输入样例:

Tomcat is a male ccatat
cat

输出样例:

Tom is a male 
#include<iostream>
#include<string>
using namespace std;
int main(){
	string s1,s2;
getline(cin,s1);
getline(cin,s2);
while(s1.find(s2)<s1.length()){
	s1=s1.erase(s1.find(s2),s2.length());
}
cout<<s1<<endl;
	return 0;
}

7-3 十进制转十六进制 (15 分)

编写一个程序,提示用户输入0~15之间的一个整数,显示其对应的十六进制数。

输入格式:

输入一个0~15之间的整数。

输出格式:

若输入的整数在0~15范围内,则输出对应的十六进制数。否则输出“Invalid input”。

输入样例:

11

输出样例:

B
#include<stdio.h>
int main(){
	int n;
	scanf("%d",&n);
	if(n<=15&&n>=0){
		printf("%X\n",n);
	}else{
		printf("Invalid input\n");
	}
	return 0;
}

7-4 Swan学院社团招新 (20 分)

Swan学院社团招新,招新宣讲会分散在不同时间段,大一新生小花花想知道自己最多能完整的参加多少个招新宣讲会(参加一个招新宣讲会的时候不能中断或离开)。 【问题说明】这个问题是对几个相互竞争的招新宣讲会活动进行调度,它们都要求以独占的方式使用某一公共资源(小花花)。调度的目标是找出一个最大的相互兼容的活动集合。 活动选择问题就是要选择出一个由互相兼容的问题组成的最大子集合。 【温馨提示】应先将所有的活动按照结束时间升序排列,然后再选择可能的时间组合,并求出最大的组合数,使用qsort()排序函数是一个不错的选择。qsort 的函数原型是: void qsort(voidbase,size_t num,size_t width,int(__cdeclcompare)(const void,const void)); 功 能: 使用快速排序例程进行排序 头文件:stdlib.h 参数: 1 待排序数组首地址;2 数组中待排序元素数量;3 各元素的占用空间大小;4 指向函数的指针,用于确定排序的顺序

输入格式:

第一行为n,表示有n个招新宣讲会,接下来n行每行两个整数表示开始时间和结束时间,由从招新会第一天0点开始的小时数表示(24小时制)。 n <= 1000 。

输出格式:

最多参加的招聘会个数。

输入样例:

在这里给出一组输入。例如:

 3  
 9 10  
 10 20  
 8 15  

输出样例:

在这里给出相应的输出。例如:

2
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
	int start,end;
}a[1005];
bool cmp(node x,node y){
	return x.end<y.end;//贪心,排序结束时间
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i].start>>a[i].end;
	}
	sort(a,a+n,cmp);
	int cnt=1,t=0;
	for(int i=1;i<n;i++){
		if(a[i].start>=a[t].end){
			cnt++;
			t=i;
		}
	}
	printf("%d\n",cnt);
	return 0;
}

7-5 建立与遍历二叉树 (25 分)

以字符串的形式定义一棵二叉树的先序序列,若字符是‘#’, 表示该二叉树是空树,否则该字符是相应结点的数据元素。读入相应先序序列,建立二叉链式存储结构的二叉树,然后中序遍历该二叉树并输出结点数据。

输入格式:

字符串形式的先序序列(即结点的数据类型为单个字符)

输出格式:

中序遍历结果

输入样例:

在这里给出一组输入。例如:

ABC##DE#G##F###

输出样例:

在这里给出相应的输出。例如:

CBEGDFA
#include<stdio.h>
void middle(){
	char c=getchar();
	if(c=='#') return;
	middle();
	printf("%c",c);
	middle();
}
int main(){
	middle();
	return 0;
}//这一题纯粹是投机取巧,因为数据结构没学好,本来不打算写,百度时偶然发现还有这种操作,遂借鉴之

7-6 字符串输入练习 (II) (15 分)

计算字符串的长度。

输入格式:

第一行一个正整数N, 然后有N行字符串。 每行一个字符串。

输出格式:

针对每行字符串,输出该串的长度。

输入样例:

2
hello world!
welcome to acm world

输出样例:

在这里给出相应的输出。例如:

12
20
#include<stdio.h>
#include<string.h>
char str[10000];
int main(){
	int n;
	scanf("%d",&n);
	getchar();//要接收换行符,否则换行符也被认为是一行字符串 
	while(n--){
	gets(str);//scanf以空白字符结束,而gets可以接收一行字符串 
		int len=strlen(str);
		printf("%d\n",len);	
	}
	return 0;
}

7-7 字符串输入练习 (III) (20 分)

输出字符串的子串。

输入格式:

每行的开始是一个正整数k,然后是一个字符串s,k和s之间用空格分开。(k大于0且小于等于s的长度)请在这里写输入格式。例如:输入在一行中给出2个绝对值不超过1000的整数A和B。

输出格式:

输出从头开始的长度为k的子串。

输入样例:

2 hello world!

输出样例:

he
#include<stdio.h>
#include<string.h>
char str[10000];
int main(){
	int n;
	scanf("%d",&n);
	getchar();
	gets(str);
	for(int i=0;i<n;i++){
		printf("%c",str[i]);
	}
	return 0;
}

7-8 字符串输入练习 (IV) (20 分)

输出字符串的子串。

输入格式:

第一行一个正整数N, 然后有N组测试。 每组测试的开始是一个正整数k,然后是一个字符串s,k和s之间用空格分开。(k大于0且小于等于s的长度)

输出格式:

对于每组测试,输出从头开始的长度为k的子串。

输入样例:

2
2 hello world!
10 welcome to acm world

输出样例:

he
welcome to
#include<stdio.h>
#include<string.h>
char str[10000];
int main(){
	int n,k;
	scanf("%d",&k);
while(k--){
	scanf("%d ",&n);
	gets(str);
	for(int i=0;i<n;i++){
		printf("%c",str[i]);
	}
	printf("\n");
}
	return 0;
}

7-9 晨阳哥哥lol之补刀 (20 分)

在非常流行的LOL游戏中,补刀是非常重要的一种基础技术。如果一个单位被对方的多个单位攻击至死,只有对该单位造成最后一次(致命的)伤害的攻击者将会获得更多的奖励(金钱和经验),这名攻击者被记录一次补兵。 现在你可以知道你的攻击力K,敌方小兵的血量X和当前的游戏时间T,众所周知小兵是拥有护甲的,然而你可没有时间在补刀的时候看他的护甲,而你也知道小兵的护甲随时间而提升,假设小兵初始护甲为10点,并且每过5分钟获得1点护甲,每1点护甲会提供百分之一的攻击削弱(如200点攻击力打10点护甲的小兵只消耗小兵180点血)。 你的任务是用编程来判断此次补刀是否成功。

输入格式:

你的攻击力K,敌方小兵当前血量X和当前游戏时间T。

输出格式:

若成功补刀输出YES,否则输出NO。

输入样例:

在这里给出一组输入。例如:

100 90 4
100 90 5
200 180 50
150 100 50

输出样例:

在这里给出相应的输出。例如:

YES
NO
NO
YES
#include<stdio.h>
int main(){
	int k,x,t;
while(~scanf("%d%d%d",&k,&x,&t)){
	double tmp=k-0.01*k*(t/5+10);
	if(tmp>=x){
		printf("YES\n");
	}else{
		printf("NO\n");
	}
}
	return 0;
}

7-10 晨阳哥哥lol之推塔 (20 分)

   在非常流行的LOL游戏中,想要获胜,必须要推塔,推塔会为全队带来经济收益和经验收益,所以在很多情况下我们要尽力推掉一座塔。
   现在假设我们在敌方塔下,我们知道自身当前血量X,自身攻击力K,敌方塔下有N(N<=20)只己方小兵,每个小兵血量为x[i],攻击力为k[i],没有敌方小兵,防御塔生命值为A,攻击力B,我们都知道,即使小兵只剩下一点血,也会消耗防御塔一次攻击,假设小兵,英雄,防御塔攻击速度相等,且防御塔优先攻击第一发,为了计算方便,假设防御塔会按照顺序(x[1]~x[n])攻击小兵。
   你的任务是判断可否推掉塔。

输入格式:

第一行先输入测试组数T,表示有T组测试数据。 第二行输入英雄生命值X,攻击力K。 第三行输入小兵数量N,随后每行行输入第i只小兵的血量x[i]和攻击力k[i]。 最后输入防御塔的血量和攻击力。

输出格式:

如果在我方死光前推掉防御塔,输出YES,否则输出NO。

输入样例:

在这里给出一组输入。例如:

3
1000 50
3
10 10 
10 10
10 10
500 20
100 50
2
10 10
10 10
500 10
2000 100
5
100 30
200 50
100 30
50  80
50  80
3000 200

输出样例:

在这里给出相应的输出。例如:

YES
YES
NO
#include<cstdio>
#include<iostream>
using namespace std;
int a[25],b[25];
int main(){
	int x,k,t,n,i,j;
	cin>>t;
	while(t--){
		cin>>x>>k;
		cin>>n;
	for( i=0;i<n;i++)
	cin>>a[i]>>b[i];
	b[n]=k;
	int fx,fk;
	cin>>fx>>fk;
	 i=0;
	 int sumk=0,flag=0;
	while(i<n){//敌方挨个攻击小兵 
		if(fk>=a[i])//击毙了小兵 
			i++;	//下一个 
		else a[i]-=fk;//小兵受伤,还可以坚持作战 
		for(j=i;j<=n;j++)
			sumk+=b[i];	//我方共同攻击敌方		
			if(sumk>=fx){
				flag=1;
				break;
			}		
	}
	while(x&&i==n){
		 if(fk>=x)//击毙了我方英雄 
			break;
		 else{
		 	x-=fk;//英雄受伤 
		 	sumk+=k;//坚持作战 
		 }
		 if(sumk>=fx){
				flag=1;
				break;
			}
	}
	if(flag)
	printf("YES\n");
	else
	printf("NO\n");
}
	return 0;
}//因为没有看懂题目逻辑,尝试写了一段代码,没能ac,网上也没有类似代码,于是向一个ac了的学弟要了代
//码来研究,总算看懂了他的代码后,在他的基础上改进了一番,总算ac。

猜你喜欢

转载自blog.csdn.net/qq_39427510/article/details/83865987