C++ 做题 Ⅳ

x33g5p2x  于2022-03-29 转载在 其他  
字(2.8k)|赞(0)|评价(0)|浏览(501)

1、确定开关门问题
宾馆里有100个房间,从1一100编了号。第一个服务员把所有的房间门都打开了,第二个服务员把所有编号是2的倍数的房间作“相反处理”,第三个服务员把所有编号是3的倍数的房间作“相反处理"…,以后每个服务员都是如此。当第100个服务员来过倍数的房间作“相反处理”,以后每个服务员也是如此。当第100个服务员来过后,哪几扇门是打开的? (所谓“相反处理”是:原来开着的门关上,原来关上的门打开。)

【分析思路】:

  1. 先设置一个100的数组,且值都为0,0代表关门,1代表开门,这样就转为真假布尔值。
  2. 设置for嵌套循环,一个是倍数从1-100的倍数(i);一个是NO1-100的门数(j);如果 j%i==0,确定是门编号的倍数,做‘相反处理 ’ a[j]=!a[j]。
  3. 接下来数组的数值就只有0/1,我们只需要1的位置,循环输出当数值为1的位置即可。
#include <iostream>
#include <cstdio>
#include<cstring>
# define MAX 100
using namespace std;
int a[MAX];
int main()
{
	int n;
	//for(int i=1;i<=n;++i) a[i]=false <==> memset(a,0,sizeof(a))
	memset(a,0,sizeof(a)); // 先设置0全部关门;1代表开门 
	for(int i=1;i<=100;++i)
		for(int j=1;j<=100;j++)
			if(j%i==0) a[j]=!a[j]; // i是倍数,j是100门数,余尽是做'相反处理' 
	cout<<"开着的门有:"<<endl;
	for(int i=1;i<=100;++i)
		if(a[i]) 		//判断是否开门 
			cout<<i<<" "; // 输出那几扇门开着 
	return 0;
}

2、约瑟夫问题(报数出圈问题)
N个人围成一圈,第一个人开始报数,报数为M的人出圈;接着由下一个人重新开始报数,报数为M的人又退出圈,以此类推,最后圈内只剩下一个人,依次输出出圈人编号。N,M的值由键盘输入。

【分析】:

  1. 要输入N,M的值,设置一个bool数组,在圈为false,出圈为true。
  2. 要有变量记录报数(s)、记录出圈的人数(f)、记录人位置(t)。
  3. if语句模拟环圈,首尾连接,当 t==N+1,则t重新为1。
  4. 判断在圈内a[t]==false,圈内(s)+1。
  5. 当s==M,重新s=0,输出t,圈状态=true,出圈人数(f)+1。
  6. 直到f=n就退出循环。
#include <iostream>
#include <cstdio>
#include<cstring>
# define MAX 100
using namespace std;
bool a[MAX];
int main()
{
	int n,m;	 // n为多少人,m为出圈数 
	cout<<"请输入m,n的值:";
	cin>>n>>m;
	for(int i=1;i<=n;++i) a[i]=false; 
	int f=0,t=0,s=0; // s为报的数,f记录出圈人数,t记录位置 
	cout<<"出圈的位置是:";
	do{
		++t;	// 枚举圈的位置 
		if(t==n+1) t=1; // 模拟环圈,首尾连接 
		if(a[t]==false) ++s;	// 有人就报数	 
		if(s==m){		//报数=出圈数 
			s=0;		//重新开始报数 
			a[t]=true;	//出圈为true 
			cout<<t<<" "; //输出位置 
			++f;	//记录出圈的总数 
		} 
	} while(f!=n);
	cout<<endl<<"最后一个幸存是:"<<t<<endl;
	return 0;
}

3、输出数组内的最大数
输入n个整数,存放在数组a[1]-a[n]内,输出最大数,以及所在位置(n<=1000)。

#include <iostream>
#include <cstdio>
#include<cstring>
# define MAX 1000
using namespace std;
int a[MAX];
int main(){
	int k=1,n,max;
	cout<<"请输入n的值:";
	cin>>n;
	cout<<"输入数值,按空格隔开"<<endl;
	for(int i=1;i<=n;++i) 
		cin>>a[i]; 
		
	max=a[1];
	for(int i=2;i<=n;++i) {
		if(max<a[i]){
			max=a[i];
			k=i;
		}
	}
	cout<<"最大值为"<<a[k]<<endl<<"最大值位置是:"<<k<<endl;
	return 0;
}

4、冒泡排序
输入N个整数,自动按照从小到大顺序输出。(用冒泡排序)
【分析】:

  1. 冒泡排序是通过相邻两个数两两比较,每次循环比较完毕,都可以确定最后一个值是最大的,下一次比较就不用比较最后一个数了。
  2. for循环随机输入一个数组;
  3. 第一个for循环控制比较轮数,内for循环进行相邻两数的比较与交换;
  4. 最后for循环输出答案。
#include <iostream>
#include <cstdio>
#include<cstring>
# define MAX 1000
using namespace std;
int a[MAX];
int main(){
	int k=1,n,max;
	cout<<"请输入n的值:";
	cin>>n;
	cout<<"输入数值,按空格隔开"<<endl;
	for(int i=1;i<=n;++i) 
		cin>>a[i]; 
	for(int j=1;j<=n;++j) { //控制第几轮比较
		for(int i=2;i<=n-j+1;++i){ //每一轮少比较最后一个数,n-j
			int t;
			if(a[i-1]>a[i]) { // 比较与交换确定最后一个数最大
				t = a[i];
				a[i] = a[i-1];
				a[i-1] = t;	
			}
		}
	}
	for(int i=1;i<=n;++i) {
		cout<<a[i]<<" ";
	}
	return 0;
}

相关文章