【基础算法:暴力与模拟】总结
暴力枚举不知道放哪里,先跟模拟放一块吧。
模拟,顾名思义就是题目要求你做什么你就做什么,这样的题目很考验选手的代码能力。
下面放了几道小模拟例题
[NOIP2010 普及组] 数字统计 难度:红
题意

思路
对于每一个数单独统计,累加起来就是答案代码
#include <bits/stdc++.h>
using namespace std;
int cnt(int x) {
int res = 0;
while (x > 0) {
if (x % 10 == 2) res++;
x /= 10;
}
return res;
}
int l, r;
int ans;
int main() {
cin >> l >> r;
for (int i = l; i <= r; i++) ans += cnt(i);
cout << ans;
return 0;
}
[NOIP2015 普及组] 扫雷游戏 难度:红
题意

思路
暴力模拟即可代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e2 + 5;
//dx,dy表示偏移量
int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1};
int dy[8] = {1, -1, 0, 0, 1, -1, -1, 1};
int n, m;
char g[N][N];
char cnt(int x, int y) {
char res = '0';
for (int i = 0; i < 8; i++) {
int tx = dx[i] + x;
int ty = dy[i] + y;
if (g[tx][ty] == '*') res++;
}
return res;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> g[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (g[i][j] == '?') g[i][j] = cnt(i, j);
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cout << g[i][j];
}
cout << endl;
}
return 0;
}
A+B Problem(高精) 难度:橙
题意
高精度加法,相当于 a+b problem,不用考虑负数。

思路
用字符串存放,从最低位开始计算,两两相加,逢十进一,模拟即可代码
#include <bits/stdc++.h>
using namespace std;
string h_add(string a, string b) {
//为短的数加上前导0
if (a.size() < b.size()) swap(a, b);
int len = a.size() - b.size();
for (int i = 0; i < len; i++) b = "0" + b;
//用数组把每一位存起来
vector<int> x, y;
for (int i = a.size() - 1; i >= 0; i--) x.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--) y.push_back(b[i] - '0');
for (int i = 0; i < x.size(); i++) x[i] += y[i];
//逢十进一
for (int i = 0; i < x.size() - 1; i++) {
if (x[i] > 9) {
x[i + 1] += x[i] / 10;
x[i] %= 10;
}
}
//特判最高位进位的情况
if (x.back() > 9) {
x.push_back(x.back() / 10);
x[x.size() - 2] %= 10;
}
//输出答案
string ans;
for (int i = x.size() - 1; i >= 0; i--) ans.push_back(x[i] + '0');
return ans;
}
string a, b;
int main() {
cin >> a >> b;
cout << h_add(a, b);
return 0;
}
[NOIP2015 提高组] 神奇的幻方 难度:橙
题意

思路
按照题目意思来即可代码
#include <bits/stdc++.h>
using namespace std;
const int N = 50;
int n;
int x, y, cnt;
int g[N][N];
int main() {
cin >> n;
x = 1, y = (n + 1) / 2;
for (int i = 1; i <= n * n; i++) {
g[x][y] = i;
if (x == 1 && y != n)
x = n, y++;
else if (x != 1 && y == n)
x--, y = 1;
else if (x == 1 && y == n)
x++, y;
else if (x != 1 && y != n && g[x - 1][y + 1] == 0)
x--, y++;
else
x++, y;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << g[i][j] << ' ';
}
cout << endl;
}
return 0;
}
[NOIP2007 提高组] 字符串的展开 难度:橙
题意
好多,自己看吧
思路
按题意模拟,注意细节代码
#include <bits/stdc++.h>
using namespace std;
int p1, p2, p3;
string op(char l, char r) {
string x;
for (int i = l + 1; i <= r - 1; i++) {
char res = i;
if (p1 == 2 && l >= 'a' && r <= 'z') res = res - 'a' + 'A';
if (p1 == 3) res = '*';
for (int j = 1; j <= p2; j++) x += res;
}
if (p3 == 2) reverse(x.begin(), x.end());//翻转
return x + r;
}
string s, ans;
int main() {
cin >> p1 >> p2 >> p3;
cin >> s;
s = ' ' + s;
for (int i = 1; i < s.size(); i++) {
char l = s[i - 1], r = s[i + 1];
int ok = 0;//判断是不是都是字母或者数字
if ((l >= 'a' && l <= 'z' && r >= 'a' && r <= 'z') || (l >= '0' && l <= '9' && r >= '0' && r <= '9')) ok = 1;
if (s[i] == '-' && l < r && ok) {
i++;//跳过减号
ans += op(l, r);
} else ans += s[i];
}
cout << ans;
return 0;
}

浙公网安备 33010602011771号