1. 珠心算测验
来源:NOIP2014提高组
算法知识点: 枚举,哈希,预处理
复杂度:
解题思路:
由于每个数的范围都在10000以内,因此两个数的和在20000以内,所以可以开一个长度是20000的bool数组,然后枚举所有数对,将所有计算出的两数之和标记一下。
然后再枚举每个数,利用bool数组判断它是否是某两个数的和。
C++ 代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 110; int n; int a[N]; bool st[20010]; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) st[a[i] + a[j]] = true; int res = 0; for (int i = 0; i < n; i++) res += st[a[i]]; printf("%d\n", res); return 0; }
2. 比例简化
来源:NOIP2014提高组 https://ac.nowcoder.com/acm/contest/242/C
算法知识点: 枚举,欧几里得算法,数论)
复杂度:
解题思路:
由于 在100以内,因此可以枚举 的所有组合,然后判断:
- 是否互质;
- 是否大于等于 ,并且最小
C++ 代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int main() { int A, B, L; cin >> A >> B >> L; int a, b; double delta = 1e9; for (int i = 1; i <= L; i++) for (int j = 1; j <= L; j++) if (gcd(i, j) == 1) { double x = i * 1.0 / j; double X = A * 1.0 / B; if (x >= X && x - X < delta) { delta = x - X; a = i, b = j; } } cout << a << ' ' << b << endl; return 0; }
3. 扫雷游戏
来源:NOIP2015提高组 https://ac.nowcoder.com/acm/contest/243/C
算法知识点: 枚举
复杂度:
解题思路:
依次枚举每个空格,然后统计八个方向上的相邻格子有没有地雷即可。
C++ 代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 110; int n, m; char g[N][N]; int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) cin >> g[i]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) if (g[i][j] == '*') cout << '*'; else { int s = 0; for (int x = i - 1; x <= i + 1; x++) for (int y = j - 1; y <= j + 1; y++) if (x != i || y != j) { if (x >= 0 && x <n && y>= 0 && y < m && g[x][y] == '*') s++; } cout << s; } cout << endl; } return 0; }
4. 回文日期
来源:NOIP2016提高组
算法知识点: 枚举,模拟
复杂度:
解题思路:
由于只有八位数,而且回文串左右对称,因此可以只枚举左半边,这样只需枚举 总共一万个数,然后判断:
- 整个八位数构成的日期是否合法;
- 是否在范围内
C++ 代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int months[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool check(int date) { int year = date / 10000; int month = date % 10000 / 100; int day = date % 100; if (!month || month > 13 || !day) return false; if (month != 2 && day > months[month]) return false; if (month == 2) { bool leap = year % 4 == 0 && year % 100 || year % 400 == 0; if (day > 28 + leap) return false; } return true; } int main() { int date1, date2; cin >> date1 >> date2; int res = 0; for (int i = 0; i < 10000; i++) { int x = i, r = i; for (int j = 0; j < 4; j++) r = r * 10 + x % 10, x /= 10; if (r >= date1 && r <= date2 && check(r)) res++; } printf("%d\n", res); return 0; }
另外,牛客暑期NOIP真题班限时免费报名
报名链接:https://www.nowcoder.com/courses/cover/live/248
报名优惠券:DCYxdCJ