Noip 2002 普及组 复赛试题
The First:
级数求和
解题报告:
double运算即可, 注意细节.
#include <iostream> using namespace std; int main() { int k; double n = 0, Sn = 0; cin >> k; while(Sn<=k) { ++n; Sn = 1 / n + Sn; } cout << n; return 0; }
The Second:
选数
解题报告:
将给出的数据做升序全排列(回溯), 将得出的数据judge, 若是素数, 总数 + 1。
若用全排列而不用升序全排列会有重复。
#include <iostream> #include <math.h> using namespace std; int n, k, a[21], b[21] = {0}, c[21], tot = 0, aox = 0; void judge(int tot) { int k = 2; while(k <= sqrt(tot) && tot % k != 0) k++; if(k > sqrt(tot)) aox++; } int search(int l) { int i; for(i = 1; i <= n; i++) { if(b[i] == 0 && (c[l - 1] < i)) { tot = a[i] + tot; c[l] = i; b[i] = 1; if(l == k) judge(tot); else search(l + 1); b[i] = 0; tot = tot - a[i]; } } } int main() { int i; cin >> n >> k; for(i = 1; i <= n; i++) cin >> a[i]; search(1); cout << aox; return 0; }
The Third:
产生数
解题报告:
DFS求出每个数字可以变换的次数, 乘法原理相乘。
因为每个数字最多可以变成8种数字, 所以可以使用高精乘低精。
#include <iostream> #include <string> #include <cstring> using namespace std; int change[16][2], sum[10], tot = 0, judge[10], k; int a[1001], len = 0; int Mul(int l) { int x = 0; for(int i = 0; i <= len; ++i) { a[i] = a[i] * l + x; x = a[i] / 10; a[i] = a[i] % 10; } if(x != 0) a[++len] = x; } int DFS(int l) { for(int i = 1; i <= k; ++i) { if(change[i][0] == l && judge[change[i][1]] == 0) { tot++; judge[change[i][1]] = 1; DFS(change[i][1]); } } } int main() { string n; cin >> n >> k; for(int i = 1; i <= k; ++i) cin >> change[i][0] >> change[i][1]; for(int i = 0; i <= 9; ++i) { judge[i] = 1; DFS(i); sum[i] = tot + 1; tot = 0; memset(judge, 0, sizeof(judge)); } a[0] = sum[n[0] - 48]; for(int i = 1; i < n.length(); ++i) Mul(sum[n[i] - 48]); for(int i = len; i >= 0; --i) cout << a[i]; return 0; }
The Fourth:
过河卒
解题报告:
将马和马能跳到的位置标记成1, 然后dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
#include <iostream> using namespace std; long long b[30][30]; int a[30][30]; int main() { int x, y, n, m; cin >> x >> y >> n >> m; x = x + 2; y = y + 2; n = n + 2; m = m + 2; a[n][m] = 1; a[n + 1][m + 2] = 1; a[n + 1][m - 2] = 1; a[n + 2][m - 1] = 1; a[n + 2][m + 1] = 1; a[n - 1][m + 2] = 1; a[n - 1][m - 2] = 1; a[n - 2][m + 1] = 1; a[n - 2][m - 1] = 1; for(int i = 2; i <= x; ++i) for(int j = 2; j <= y; ++j) { b[2][2] = 1; if(a[i][j] != 1) b[i][j] = b[i - 1][j] + b[i][j - 1]; } cout << b[x][y]; return 0; }
The End..