Bootstrap

北科程序设计第十一周上机

目录

1. 小球第n次反弹的高度

 2. 0~99之间的一串随机数

 3. 公共子序列

4. 按列输出二维数组

 5. 字符串匹配

6. 荷兰国旗问题

 7. 桶排序

8. 在一维数组中查找最大值,要求用递归实现。

9. 蛇形填数

 10. 折半查找


 

1. 小球第n次反弹的高度

题目正文:一个球从100m高度落下,每次反弹是之前高度的一半,求第n次反弹多高?(即,第一次50m,第二次25m......)

输入输出说明:

输入:1

输出:50

初始代码:

#include "iostream"

using namespace std;

int main()

{    

    //write your own codes

    return 0;

}

示例代码:

#include "iostream"
#include <cmath>
using namespace std;
int main()
{    
     int n;
	 cin>>n;
	 float result=100.0/(pow(2,n));
	 cout<<result<<endl;
     return 0;
}

 2. 0~99之间的一串随机数

【题目描述】

在计算机中,通常采用线性同余法产生随机数,即随机数序列a0, a1, …, an满足:

a0 = seed,

an = (b*an-1 + c) % m ,n = 1, 2, ……

其中,b≥0,c≥0,m>0,seed≤m。

seed称为随机种子,当b、c和m的值确定后,给定一个随机种子,由式产生的随机数序列也就确定了。

输入seed,b,c,m 输出随机序列的前5项 (a0到a4)

【输入格式】

一行4个整数分别表示 seed ,b,c,m

【输出格式】

一行4个整数表示随机序列的前4项(!! 注意: 中间有两个空格分隔)

【样例输入】

10 2 4 5

【样例输出】

a0 10

a1 4

a2 2

a3 3

a4 0

示例代码:

#include <iostream>
using namespace std;
int main()
{    
     int seed,b,c,m,a[5];
     cin>>seed>>b>>c>>m;
     a[0]=seed;
     cout<<"a0"<<"  "<<seed<<endl;
     for (int i=1;i<=4;i++)
    {
	    a[i]=(b*a[i-1]+c)%m;
	    cout<<"a"<<i<<"  "<<a[i]<<endl;
    }
    return 0;

}

 3. 公共子序列

【题目描述】

对主串s按序号递增的顺序选出一个子串t,称t是s的子序列。

例如,对于主串s="abcbda",子串"bcd"是s的一个子序列。

给定两个主串s1和s2,当子串t既是s1的子序列又是s2的子序列时,称t是s1和s2的公共子序列。

例如,主串s1="abcbda",主串s2="abcab",子串"acb"是主串s1和s2的公共子序列。

要求编写程序,判断给定的子串是否为两个主串的公共子序列。

【输入格式】

一行三个字符串(中间用一个空格分隔),分别表示两个主串 s1,s2 和 t

【输出格式】

按要求输出 "yes" 或 "no" (不带引号)

【样例输入1】

abcdef abcffff abc

【样例输出1】

yes

【样例输入2】

abcdef ffff abc

【样例输出2】

no

示例代码:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{    
     string a;
	 string b;
	 string c;
	 cin>>a>>b>>c;
	 int flag1=a.find(c);//没找到返回-1 
	 int flag2=b.find(c);//没找到返回-1 
	 if ((flag1!=-1)&&(flag2!=-1))//表示找到了 
	 {
		cout<<"yes"<<endl;
	 }
	 else cout<<"no"<<endl;
	 return 0;
}

4. 按列输出二维数组

【题目描述】

给定两个正整数m,n,以及一个m * n的二维数组,将这个数组按列输出。(输出转置后的矩阵)

【输入格式】

输入共 m 行 ,每行 n 个数表示一个二维数组

【输出格式】

输出共 n 行 ,每行 m 个数表示原数组按列输出后的结果(转置后的矩阵)

【样例输入】

3 4

1 2 3 4

5 6 7 8

9 10 11 12

【样例输出】

1 5 9

2 6 10

3 7 11

4 8 12

示例代码:

#include <iostream>
using namespace std;
int main()
{
	int M[10][10];
	int m,n;
	cin>>m>>n;
	for (int i=0;i<=m-1;i++)
	{
		for (int j=0;j<=n-1;j++)
		{
			cin>>M[i][j];
		}
	}
	for (int i=0;i<=n-1;i++)
	{
		for (int j=0;j<=m-1;j++)
		{
			cout<<M[j][i]<<" ";
			if(j==m-1) cout<<endl;
		}
	}
	return 0;
}

 5. 字符串匹配

【题目描述】

给定一个主串s和一个模式(也称为子串)t,在主串s中寻找模式t的过程称为字符串匹配,也称为模式匹配。

如果匹配成功,则返回模式t中第一个字符在主串s中的序号。

【输入格式】

一行两个字符串(中间用一个空格分隔),分别表示 s 和 t 。

【输出格式】

如果匹配成功,输出 "find at X" (不带引号),其中 X 表示匹配成功时模式串 t 中第一个字符在主串 s 中的序号

反之输出 "can't find" (不带引号)

【样例输入1】

qwert we

【样例输出1】

find at 2

示例代码:

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
	string s,r;
	cin>>s>>r;
	int flag=s.find(r);
	if (flag!=-1)	cout<<"find at "<<s.find(r)+1<<endl;
    else cout<<"can't find"<<endl;
	return 0;
}

6. 荷兰国旗问题

【题目描述】

要求重新排列一个由Red、White和Blue(这是荷兰国旗的颜色)构成的数组,使得所有的Red都排在最前面,White排在其次,Blue排在最后。

【输入格式】

一行多个字符串,每个字符串都是 "Red" "White" 或 "Blue"

【输出格式】

一行按要求将原来的多个字符串排序后输出。

【样例输出】

Red White Blue Blue Red White White Blue White Red

【样例输出】

Red Red Red White White White White Blue Blue Blue

【提示】

strtok()函数可从一个字符串中提取以特殊字符分隔的子串。

示例代码:

#include <iostream>
#include <cstring>
using namespace std; 
int main()
 {
    char inStr[256];
    cin.getline(inStr, 256);

    // 用于统计每种颜色出现的次数
    int redCount = 0;
    int whiteCount = 0;
    int blueCount = 0;

    char* pch;
    pch = strtok(inStr, " ");
    while (pch!= NULL) 
	{
        if (strcmp(pch, "Red") == 0)
	    {
            redCount++;
        } 
		else if (strcmp(pch, "White") == 0)
	    {
            whiteCount++;
        } 
		else 
		{
            blueCount++;
        }
        pch = strtok(NULL, " ");
    }

    // 按顺序输出排列好的颜色字符串
    for (int i = 0; i < redCount; i++) {
        cout << "Red ";
    }
    for (int i = 0; i < whiteCount; i++) {
        cout << "White ";
    }
    for (int i = 0; i < blueCount; i++) {
        cout << "Blue ";
    }

    return 0;
}

 7. 桶排序

好奇的C同学想找到高效的排序算法。TA知道在特定条件下可以使用桶的思想排序。

有数列有十个元素,每个元素均在0—99之间。

将元素放入对应的桶(n放入n号桶),桶中记录元素个数,再依次输出

【输入格式】

一行10个数

【输出格式】

一行10个数,表示原数列排序后的数列

【样例输入】

1 5 8 9 7 4 2 3 6 0

【样例输出】

0 1 2 3 4 5 6 7 8 9

示例代码:

#include <iostream>
using namespace std;
int main()
{
	int a[10],t;
	for (int i=0;i<=9;i++) 
	{
		cin>>a[i];
	}
	for (int i=0;i<9;i++)
	{
		for (int j=0;j<9-i;j++)
		{
			if(a[j]>a[j+1])
			{
			    t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	for (int i=0;i<=9;i++)
	{
		cout<<a[i]<<" ";
	}
	return 0;
}

 

8. 在一维数组中查找最大值,要求用递归实现。

【题目描述】

设递归函数Max对数组的处理区间是[low, high],以中间位置mid将原问题分解为两个子问题,查找区间分别是[low, mid]和[mid+1, high],在左半区间查找最大值maxL,在右半区间查找最大值maxR,则maxL和maxR的较大值即是区间[low, high]的最大值。

多次比较得出整个数组最大值。

【输入格式】

输入共一行,第一个数是 n 表示数组中元素的个数。

接下来有 n 个数,表示数组内各个元素的值。

【输出格式】

输出一个数表示数组中最大的元素的值。

【样例输出】

7 1 2 3 4 7 6 5

【样例输出】

7

示例代码:

#include <iostream>
using namespace std;

// 递归函数,用于查找数组在[low, high]区间内的最大值
int Max(int arr[], int low, int high) {
    if (low == high) {  // 当区间只有一个元素时,该元素就是最大值
        return arr[low];
    }
    int mid = (low + high) / 2;  // 计算中间位置,划分区间
    int maxL = Max(arr, low, mid);  // 递归查找左半区间[low, mid]的最大值
    int maxR = Max(arr, mid + 1, high);  // 递归查找右半区间[mid + 1, high]的最大值
    return maxL > maxR? maxL : maxR;  // 返回左右区间最大值中的较大值
}

int main() {
    int n;
    cin >> n;
    int arr[n];
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    cout << Max(arr, 0, n - 1) << endl;  // 调用递归函数查找整个数组的最大值并输出
    return 0;
}

9. 蛇形填数

【题目描述】

在 n* n方阵里填入1,2……n * n,要求填成蛇形。例如 n=4 时方阵为:

10 11 12 1

9 16 13 2

8 15 14 3

7 6 5 4

上面的方阵中,多余的空格只是为了便于观察规律,不必严格输出。n<=10

【输入格式】

一行一行个整数n

【输出格式】

一个 n*n 的矩阵表示蛇形填数后的结果。

要求:每一个数字要占4位,不足用空格补全。

【样例输入】

2

【样例输出】

4 1

3 2

示例代码:

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
     int n;
	 cin>>n;
	 int sum[100][100]={0};
	 int num=1;
	 for (int i=0;i<n/2;i++)
	 {
	 	int x=i;
	 	int y=n-i-1;
	    for (x=i;x<=n-2-i;x++)
	    {
	     	sum[x][y]=num;
	     	num++;
		}
	    for (y=n-i-1;y>i;y--)
	    {
	     	sum[x][y]=num;
	     	num++;
		}
		for (x=n-1-i;x>i;x--)
	    {
	     	sum[x][y]=num;
	     	num++;
		}
		for (y=i;y<=n-2-i;y++)
	    {
	     	sum[x][y]=num;
	     	num++;
		}
	 }
	 if (n%2==1)
	 {
	     int c=n/2;
	     sum[c][c]=num; 	
	 }	
	 for (int j=0;j<n;j++)
	 {
	 	cout<<sum[0][j]<<setw(4);
	 }
	 cout<<endl;
	 for (int i=1;i<n;i++)
	 {
	 	for (int j=0;j<n;j++)
	 	{
	 		cout<<setw(4)<<sum[i][j]<<setw(4);
	    }
	    cout<<endl;
	 }
	 return 0;
} 

 10. 折半查找

【题目描述】

应用折半查找方法在一个有序序列{ 1, 3, 5, 7, 9, 11, 13, 15,17, 19 }中查找值为k的元素。

应用折半查找方法在一个升序序列中查找值为k的元素。若查找成功,返回元素k在序列中的位置,若查找失败,返回失败信息。

【算法提示】

折半查找利用序列有序的特点,其查找过程是:取序列的中间元素作为比较对象,若k与中间元素相等,则查找成功;若k小于中间元素,则在中间元素的左半区继续查找;若k大于中间记录,则在中间元素的右半区继续查找。不断重复上述过程,直到查找成功,或查找区间为空,查找失败。

【输入格式】

一行一个数 x,表示要查找的数

【输出格式】

如果在题目中的序列中存在 x 则输出 "yes" ,反之输出 "no" (不带引号)

【样例输入1】

1

【样例输出1】

yes

【样例输入2】

200

【样例输出2】

no

示例代码:

#include <iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int flag=0;
	int num[]={ 1, 3, 5, 7, 9, 11, 13, 15,17, 19 };
	for (int i=0;i<=9;i++)
	{
		if (n==num[i])
		 flag=1;
	}
	if (flag) cout<<"yes";
	else cout<<"no"<<endl;
	return 0;
}

能力有限,暂未学会二分法,以后纠正

;