目录
第一题
题目链接
题目解析
代码原理
代码编写
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int all[8][9] = {{4,9,2,3,5,7,8,1,6},{2,9,4,7,5,3,6,1,8},{4,3,8,9,5,1,2,7,6},{8,3,4,1,5,9,6,7,2},{2,7,6,9,5,1,4,3,8},{6,7,2,1,5,9,8,3,4},{8,1,6,3,5,7,4,9,2},{6,1,8,7,5,3,2,9,4}};
int ok(int a[9])
{
int cnt = 0, ans = -1;
for(int i = 0; i < 8; i++)
{
bool truth = true;
for(int j = 0; j < 9; j++)
{
if(a[j] == 0) continue;
if(a[j] != all[i][j])
{
truth = false;
break;
}
}
if(truth)
{
cnt++;
ans = i;
}
}
if(cnt == 1) return ans;
else return -1;
}
int main()
{
// 请在此输入您的代码
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int data[9];
for(int i = 0; i < 9; i++)
{
cin >> data[i];
}
int index = ok(data);
if(index == -1) cout << "Too Many" << endl;
else
{
cout << all[index][0] << " " << all[index][1] << " " << all[index][2] << endl;
cout << all[index][3] << " " << all[index][4] << " " << all[index][5] << endl;
cout << all[index][6] << " " << all[index][7] << " " << all[index][8] << endl;
}
return 0;
}
第二题
题目链接
题目解析
想必还是比较抽象,因此博主邀请了一位粉丝,与博主模拟了这个小游戏,下面的视频为大家详细解答
蓝桥杯真题讲解
代码原理
代码编写
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
bool op(string& x, string& z)
{
if(x.size() == 0) return false;//先判断进来的这个字符串a长度是否为0,如果为0则直接返回false
char front = x[0];//取出字符串a的首元素
long long i = z.find(front);//其次获取它在字符串z中的位置,即检查是否已经出现在了桌面
bool ans = true;//用于控制出手顺序
if(i != string::npos)//即桌面上已经有这张牌了
{
x.insert(x.end(), front);//先将front放回队尾
for(int j = 0; j <= i; j++)
{
x.insert(x.end(), z[j]);//将z中的字符从0到i位置的字符尾插到a中
}
z.erase(0, i + 1);//插入结束后,要删除
}
else//桌面上没有这个字符
{
z.insert(z.begin(), front);
ans = false;
}
x.erase(x.begin());
return ans;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
string a, b, c;
cin >> a >> b;
bool flagA = true, flagB = false;//先假设a赢,b输
while(1)
{
if(flagA)
{
flagA = op(a,c);
if(a.size() == 0)
{
cout << b << endl;
break;
}
flagB = !flagA;
}
if(flagB)
{
flagB = op(b,c);
if(b.size() == 0)
{
cout << a << endl;
break;
}
flagA = !flagB;
}
}
return 0;
}
本题总结
思路梳理:
核心模拟部分:先判断要操作的字符串的长度是否为0,如果为0直接返回false。反之,先取出字符串的第一个元素,再用这个元素去z(桌面上)找是否有这个字符(即是否有这张牌),如果有,那么将原本已经拿出来的字符放回该自己牌中的队尾,再将桌面上从第一个字符到第i个字符(就是与原本要插入的字符相同的位置)放回自己牌中的队尾,并且不改变ans的值(用于控制出手顺序)如果没有相同字符,将取出的字符放到桌面上字符串的队首,并且更改ans的值,注意记得删除原字符串里已经取出的字符。
次要部分(main函数里的):假设a能出牌,b不能出牌,然后进行操作(就是核心模拟部分),先判断a的字符串长度是否为0。如果为0,则输出b赢。如果不为0,则更改flagb的值(flaga的值取反即可)
第三题
题目链接
题目解析
代码原理
用哈希表统计出每个字母的次数,用最大减最小
代码编写
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios:: sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
string s;
int hash[26] = { 0 };
cin >> s;
for(int i = 0; i < s.size(); i++)
{
hash[s[i] - 'a']++;
}
int maxsize = 0, minsize = 0x3f3f3f3f;
for(int i = 0; i < s.size(); i++)
{
maxsize = max(maxsize, hash[s[i] - 'a']);
minsize = min(minsize, hash[s[i] - 'a']);
}
cout << maxsize - minsize << endl;
return 0;
}
本题总结
本题又用到了前几篇所总结过的哈希表,那么在比赛中,凡是有涉及到统计的优先考虑这个哈希表。
第四题
题目链接
题目解析
代码原理
这里只给大家演示了当u和start都是1的情况,基本逻辑是模拟了下面这张图
后面的图,就劳烦各位小伙伴们自己去画一下图吧(太多了,画板画不下),结束条件这里有两种情况,第一种是start != u这种情况就直接return即可,第二种就是start == u 这种情况记得先更新结果再return。
代码编写
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
bool st[N];
int ans = -0x3f3f3f3f;
void dnf(int cur, int start, int len)
{
if(st[cur])
{
if(cur == start)
{
ans = max(ans, len);
}
return;
}
st[cur] = true;//修改状态
dnf(a[cur], start, len + 1);//递归
st[cur] = false;//恢复状态
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n = 0;
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
}
for(int i = 1; i <= n; i++)
{
memset(st, false, sizeof(st));
dnf(i, i, 0);
}
cout << ans << endl;
return 0;
}
本题总结
第五题
题目链接
题目解析
代码原理
代码编写
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
ll a[N];
int gc(int c, int e)
{
if(e == 0) return c;
return gc(e, c % e);//递归
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n = 0;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a, a + n);
int d = 0;
for(int i = 1; i < n; i++)
{
d = gc(d, a[i] - a[i - 1]);
}
if(d == 0) cout << n;
else cout << (a[n - 1] - a[0]) / d + 1 << endl;
return 0;
}
本题总结
第六题
题目链接
题目解析
代码原理
这里的代码原理,原本是不想写的,但博主考虑到看这篇文章的小伙伴们的水平都不一样,因此博主决定还是简单带一下代码原理这一部分
代码编写
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n = 0, m = 0;//n代表行,m代表列
cin >> n >> m;
int a[n][m];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
cin >> a[i][j];
}
}
for(int i = 0; i < m; i++)//原来的列变成行
{
for(int j = n - 1; j >= 0; j--)//原来的行变成列
{
cout << a[j][i] << " ";//记得互换一下i和j的位置
}
cout << endl;
}
return 0;
}
第七题
题目链接
题目解析
代码原理
那么先前说过但凡出现统计次数的就用哈希表,这里博主其实想用哈希map的但是好像蓝桥杯比赛的编程环境无法使用,因此这题我们使用map来解题,当然这题也可以直接使用哈希来解题,那么代码我都放在下面供大家参考
代码编写
错误的思路
使用了map
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
string s;
cin >> s;
map<char, int> mp;
for(int i = 0; i < s.size(); i++)
{
mp[s[i]]++;
}
int maxCount = 0;
char maxChar;
for(int i = 0; i < s.size(); i++)
{
if(maxCount < mp[s[i]])
{
maxCount = mp[s[i]];
maxChar = s[i];
}
}
cout << maxChar << endl;
cout << maxCount << endl;
return 0;
}
使用了hash
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
string s;
cin >> s;
int hash[26] = { 0 };
for(int i = 0; i < s.size(); i++)
{
hash[s[i] - 'a']++;
}
int maxCount = -0x3f3f3f3f;
char maxChar;
for(int i = 0; i < s.size(); i++)
{
if(maxCount < hash[s[i] - 'a'])
{
maxCount = hash[s[i] - 'a'];
maxChar = s[i];
}
}
cout << maxChar << endl;
cout << maxCount << endl;
return 0;
}
结果图
正确的思路
代码
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
string s;
cin >> s;
int hash[N] = {0};
for(int i = 0; i < s.size(); i++)
{
hash[s[i] - 'a']++;
}
int maxCount = -0x3f3f3f3f;
char maxChar;
for(int i = 0; i < s.size(); i++)
{
if(maxCount <= hash[s[i] - 'a'])
{
if(maxCount < hash[s[i] - 'a'])
{
maxCount = hash[s[i] - 'a'];
maxChar = s[i];
}
else if(maxCount == hash[s[i] - 'a'])
{
maxCount = hash[s[i] - 'a'];
maxChar = s[i];
}
}
}
cout << maxChar << endl;
cout << maxCount << endl;
return 0;
}
结果图
博主翻阅其他博主的文章,找到了问题所在,那么首先感谢一下这位博主
博主翻阅了这位博主的文章,发现博主原本的思路是没有问题,但是少考虑了一种情况。那么是什么情况呢?听博主细细道来。
我们先来回忆一下,一开始的思路。
思路:利用哈希表或者map依次遍历,并且统计每个字母次数,然后设置最大值的初始值,再来一次循环,比较出最大的次数,最后输出出现最多出现次数的字母以及次数。
这个思路看似没有问题,但是还是存在一个小bug,就如同这位博主所说的一样,因为数组s中已经是按照字典序排列。但是存在一种情况,即一个字符串中有两个字母的出现次数是一样的,且都是最大次数,而我们只需要输出排在前面的结果即可。
本题总结
涉及统计次数的优先考虑哈希表,若是还有涉及其它变量则考虑使用map
本篇文章的内容就先到这里,关于map的题后面会涉及以及完整的一些用法也会有总结,精彩持续为您更新,敬请期待!