仿真实验室第二次培训题解

发布时间 2023-08-08 00:55:17作者: cxy8

7-1

直接根据题目模拟就行,这道题目类似排队,排队可以用队列实现,c++的stl里面有queue可以学习

#include <bits/stdc++.h> 
#define x first
#define y second

using namespace std;
queue<string>q;
char c[100];
int n; 
void solve()
{
	scanf("%d", &n);
	while(n --)
	{
		cin >> (c + 1);
		//如果当前是in的话我们就让这个同学入队
		if(c[1] == 'i')
		{
			string name;
            cin >> name;
			q.push(name); 
		}
		//如果,当前是out,我们就将队头元素出队
		else if(c[1] == 'o')	q.pop();
		//如果当前是q的话,我们就查询队头元素,题目中的样例给的也提示我们队空这种情况
		else	
		{
			if(q.size() == 0)	cout << "NULL" << endl;
			else	
			{
				string t = q.front();
				cout << t << endl;
			}
		}
	}
}

int main()
{
//	freopen("1.in", "r", stdin);
	solve(); 
	return 0;
}

7-2

这道题目也是直接模拟就行,用c++的map统计一个单词中字母出现的次数,然后找到最大出现次数和最小出现次数,判断一下两者之差是不是质数就可以了。题目中的描述已经很清楚了。
这里判断质数用试除法,时间复杂度是O(n^(3/2)),数据量是100不会tle。

#include <bits/stdc++.h> 
#define x first
#define y second

using namespace std;
const int N = 110;
string str;
int n; 
map<char, int>mp;
//试除法判断是否为质数
bool is_prime(int n)
{
    if(n < 2)   return false;
	//这里只需要枚举到根号n即可具体证明可以百度,这里携程i <= n / i的形式比较好,因为如果携程i * i <= n的话当i比较大的时候可能会爆int
    for(int i = 2; i <= n / i; i ++)
    if(n % i == 0)  
        return false;
    return true;
}

void solve()
{
	cin >> str;
	//统计单词中每个字母出现的次数
	for(int i = 0; i < str.size(); ++ i)
		++ mp[str[i]];
	//找出现次数的最大值和最小值
	int max_cnt = 0;
	int min_cnt = 99999;
	for(auto item : mp)
	{
		if(item.y > max_cnt) max_cnt = item.y;
		if(item.y < min_cnt) min_cnt = item.y;
	}
	int k = max_cnt - min_cnt;
	if(is_prime(k))
	{
		puts("Lucky Word");
		cout << k << endl;;
	}
	else	
	{
		puts("No Answer");
		cout << 0 << endl;
	}
}

int main()
{
//	freopen("1.in", "r", stdin);
	solve(); 
	return 0;
}

7-3

思路:枚举,我们直接取枚举2进制下和3进制下错误的每一位,然后枚举一下错误的情况,判断是否相等即可,因为题目中说了有唯一解,所以我们一定可以找到。

#include <bits/stdc++.h> 
#define x first
#define y second

using namespace std;
map<int, int>mp;
//将任意进制(10进制以内)转换成10进制,其实就是简单的模拟
int cal(string x, int p)
{
	int cnt = 0;
	for(int k = 0; k < x.size(); ++ k)
		cnt = cnt * p + (x[k] - '0');
	return cnt; 
}
void solve()
{
	string a1, a2, tmp1, tmp2;
	cin >> a1 >> a2;
	//枚举每一种情况
	for(int i = 0; i < a1.size(); ++ i)
	{
		for(int j = 0; j < a2.size(); ++ j)
		{
			tmp1 = a1;
			tmp2 = a2;
			if(a1[i] == '1')	tmp1[i] = '0';
			else tmp1[i] = '1';
			int num1 = cal(tmp1, 2);
			for(int k = 0; k <= 2; ++ k)
			{
				if(a2[j] != k + '0')
				{
					tmp2[j] = k + '0';
					int num2 = cal(tmp2, 3);
//					cout << num1 << ' ' << num2 << endl;
					//判断当前是否相等
					if(num1 == num2)
					{
						cout << num1 << endl;
						return;
					}
				}	
			}
		}	
	}	
}

int main()
{
//	freopen("1.in", "r", stdin);
	solve(); 
	return 0;
}

7-4

这个题目和第一道题的队列类似,因为n,m比较小直接模拟即可

#include <bits/stdc++.h> 
#define x first
#define y second

using namespace std;
queue<int> q;
vector<int> ans;
int n, m, cnt = 1;
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; ++ i)    q.push(i);
    bool st = false;
    while(q.size())
    {
        if(cnt == m)
        {
            int t = q.front();q.pop();
            ans.push_back(t);
            cnt = 1;
        }
        else
        {
            int t = q.front();q.pop();
            q.push(t);
            cnt ++;
        }
    }
    for(auto x : ans)   cout << x << ' ';
    return 0;
}

7-5

这里需要提醒大家的是100位的数c++的整形是存不下的,long long也只能存18位左右的数据,这里如何你直接用int或者long long的话会爆int或long long,这里我们用字符串存数据,也就是我们经常说的高精度,如果你不想写高精度的话,可以用python,python可以直接存下,当然这里为了锻炼各位的编程能力,还是建议用高精度写一下。

#include <bits/stdc++.h> 
#define x first
#define y second

using namespace std;


void solve()
{
	string a, b;
	while(cin >> a >> b)
	{
		if(a.size() > b.size())	
		{
			cout << "Greater" << endl;
			continue;
		}
		else if(a.size() < b.size())
		{
			cout << "Less" << endl;
			continue;
		}
		else
		{
			bool st = false;
			for(int i = 0; i < a.size(); ++ i)
			{
				if(a[i] > b[i])	
				{
					st = true;
					cout << "Greater" << endl;
					break;
					
				}
				else if(a[i] < b[i])
				{
					st = true;
					cout << "Less" << endl;
					break;
				}
			}
			if(!st)	cout << "Equal" << endl;
		}
	}
}

int main()
{
//	freopen("1.in", "r", stdin);
	solve(); 
	return 0;
}

7-6

这也是道模拟题直接模拟即可,这里推荐大家学一下c++的sort函数,用起来很方便,支持结构体排序

#include <bits/stdc++.h> 
#define x first
#define y second

using namespace std;
const int N = 210;
int a[N], b[N]; 
int n, r; 


void solve()
{
	cin >> n >> r;
	for(int i = 1; i <= n; ++ i)	scanf("%d", &a[i]), b[i] = a[i];
	if(2 * r >= n)
		for(int i = 1; i <= n; ++ i)	
		{
			cout << a[i];
			if(i != n)	cout << ' ';
		}
	else
	{
		//将题目中要求的排序片段进行排序
		sort(b + 1 + r, b + 1 + n - r);
		for(int i = 1; i <= n; ++ i)
		{
			cout << b[i];
			if(i != n)	cout << ' ';
		}
	}
}

int main()
{
//	freopen("1.in", "r", stdin);
	solve(); 
	return 0;
}

7-7

这里我用的是递归取枚举排列,然后需要注意的是按字典序输出,不懂什么是字典序的可以自行百度,这里大家可以去学习一下d深度优先搜索(dfs)是一种很常用的算法,任何问题我们都可以通过搜索去解决,不过搜索的坏处就是时间复杂度很高

#include <bits/stdc++.h> 
#define x first
#define y second
 
using namespace std;
 
const int N = 10;
char a[N];
// path数组用于记录我们枚举的排列,st用来标记每个数是否用过
int path[N], st[N]; 
int n;
//u是我们枚举到那个位置了
void dfs(int u)
{
	//当我们枚举完所有的n个位置的数这时候我们就找到了一种排列
	if(u == n )
	{
		for(int i = 0; i < n; i ++)	cout << a[path[i]];
		puts(""); 
	}
	//枚举第u个位置应该是那个数
	for(int i = 0; i < n; i ++)
	{
		//如果这个数已经用过了,我们直接continue
		if(st[i])	continue;
		//如果没有用过,我们就在当前位置放这个数,并且标记这个数已经用过(排列中一个数只能用一次)
		path[u] = i;
		st[i] = 1;
		//递归到下一层
		dfs(u + 1);
		//记得回溯,因为我们当前这个位置还需要去枚举放其他数字的情况
		st[i] = 0;
	}
}
 
 
int main()
{
	scanf("%s", a);
	for(int i = 0; a[i]; i ++)	n ++;
	//这里我们预处理一下之前的字符串数组,让字符串内部本身就是按字典序排列的
	sort(a, a + n); 
	//开始枚举
	dfs(0); 
	return 0;
} 

7-8

这里还是c++中sort函数的使用,另外大家注意一下输入就行.

#include <bits/stdc++.h> 
#define x first
#define y second

using namespace std;
const int N = 10010;
int a[N]; 
int n; 


void solve()
{
	int x;
	while(cin >> x)	a[++ n] = x;
	sort(a + 1, a + 1 + n);
	cout << "从标准设备读入数据,直到输入是非整型数据为止" << endl;
	for(int i = 1; i <= n; ++ i)	cout << ' ' << a[i];

}

int main()
{
//	freopen("1.in", "r", stdin);
	solve(); 
	return 0;
}