模拟
模拟算法通过模拟实际情况来解决问题,一般容易理解但是实现起来比较复杂,有很多需要注意的细节,或者是一些所谓很“麻烦”的东西。模拟题一般不涉及太难的算法,一般就是由较多的简单但是不好处理的部分组成的,考察选手的细心程度和整体的逻辑思维。
一般为了使得模拟题写的逻辑清晰一些,经常会写比较多的小函数来帮助解题,例如int和string的相互转换、回文串的判断、日期的转换、各种特殊条件的判断等等。
例题
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int mp[N][N];
int ans[N][N];
int main()
{
int n, m;
cin >> n >> m;
// 输入矩阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> mp[i][j];
}
}
// 处理矩阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (mp[i][j] == 1) {
ans[i][j] = 9;
continue;
}
// 遍历周围 8 个方向
for (int i_ = max(1, i - 1); i_ <= min(n, i + 1); i_++) {
for (int j_ = max(1, j - 1); j_ <= min(m, j + 1); j_++) {
if (mp[i_][j_] == 1) {
ans[i][j]++;
}
}
}
}
}
// 输出结果
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cout << ans[i][j] << ' ';
}
cout << endl;
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N = 150;
int a[N][N];
int r[N], c[N];
int cnt = 0;
int main() {
int n, m, t;
cin >> n >> m;
// 初始化矩阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = 0;
}
}
// 输入 t 对坐标
cin >> t;
for (int i = 1; i <= t; i++) {
cin >> r[i] >> c[i];
}
// 标记初始的 (r[i], c[i]) 坐标为 1
for (int i = 1; i <= t; i++) {
a[r[i]][c[i]] = 1;
}
// 设置扩展的步数 k
int k;
cin >> k;
// 按 k 次扩展
while (k--) {
// 创建一个临时数组用于保存扩展后的状态
int temp[N][N] = {0};
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] == 1) {
temp[i][j] = 1;
if (i > 1) temp[i-1][j] = 1; // 上
if (i < n) temp[i+1][j] = 1; // 下
if (j > 1) temp[i][j-1] = 1; // 左
if (j < m) temp[i][j+1] = 1; // 右
}
}
}
// 更新 a 数组
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = temp[i][j];
}
}
}
// 统计所有 1 的数量
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] == 1) {
cnt++;
}
}
}
cout << cnt << endl;
return 0;
}
蓝桥杯498 回文日期
分析:我们可以编写这么几个函数
1.从int转换为指定位数的string函数
2.从string转换为int的函数
3.判断闰年的函数
4.判断日期是否合法的函数
5.判断字符串是否是回文的函数
6.判断字符串是否是ABABBABA型回文的函数
#include <bits/stdc++.h>
using namespace std;
int s2i(string s) {
int res = 0;
for (const auto &i : s) {
res = res * 10 + i - '0';
}
return res;
}
string i2s(int x, int w) {
string res;
while (x) {
res += (x % 10) + '0';
x /= 10;
}
while (res.size() < w) res += '0';
reverse(res.begin(), res.end());
return res;
}
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
bool isok(int year, int month, int day) {
int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (isLeapYear(year)) {
days[2] = 29;
}
return month >= 1 && month <= 12 && day >= 1 && day <= days[month];
}
bool isHuiwen(string s) {
for (int i = 0; i < s.size() / 2; i++) {
if (s[i] != s[s.size() - 1 - i]) {
return false;
}
}
return true; // 添加返回值
}
bool isABAB(string s) {
if (!isHuiwen(s)) {
return false;
}
return s[0] == s[2] && s[1] == s[3];
}
int main() {
string s;
cin >> s;
int year = s2i(s.substr(0, 4)), month = s2i(s.substr(4, 2)), day = s2i(s.substr(6, 2));
bool ans1 = false, ans2 = false;
for (int i = year; i <= 9999; i++) {
for (int j = (i == year ? month : 1); j <= 12; j++) {
for (int k = (i == year && j == month ? day + 1 : 1); k <= 31; k++) {
if (!isok(i, j, k)) {
continue;
}
string date = i2s(i, 4) + i2s(j, 2) + i2s(k, 2);
if (!ans1 && isHuiwen(date)) {
cout << date << endl;
ans1 = true;
}
if (!ans2 && isABAB(date)) {
cout << date << endl;
ans2 = true;
}
// 如果两个条件都已满足,可以提前退出循环
if (ans1 && ans2) {
return 0;
}
}
}
}
return 0;
}