洛谷P8749 [蓝桥杯 2021 省 B] 杨辉三角形
40分做法:
思路:暴力
直接预处理出来前1000行的杨辉三角形,然后暴力枚举,找到x,输出即可
#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int N = 1e3 + 10; int n = 1000; int a[N][N]; int main() { a[1][1] = 1; for (int i = 2; i <= n; i ++) // 预处理 for (int j = 1; j <= i; j ++) a[i][j] = a[i - 1][j] + a[i - 1][j - 1]; int x; cin >> x; int cnt = 0; for (int i = 1; i <= n; i ++) // 枚举 for (int j = 1; j <= i; j ++) { cnt ++; if (a[i][j] == x) { cout << cnt; return 0; } } return 0; }
50分做法:
思路:推公式
80分做法:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
int main() {
ll n;
cin >> n;
cout << n * (n + 1) / 2 + 2;
return 0;
}
80分做法:
思路:将上面两种方法相结合
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e3 + 10;
typedef long long ll;
int n = 1000;
int a[N][N];
int main() {
ll x; cin >> x;
if (x > 1000 * 999 / 2) {
cout << x * (x + 1) / 2 + 2;
return 0;
}
a[1][1] = 1;
for (int i = 2; i <= n; i ++)
for (int j = 1; j <= i; j ++)
a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
ll cnt = 0;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= i; j ++) {
cnt ++;
if (a[i][j] == x) {
cout << cnt;
return 0;
}
}
return 0;
}
满分(100分)做法:
思路:二分
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
int n;
ll C(int a, int b) { // 求组合数函数
ll res = 1;
for (int i = a, j = 1; j <= b; i --, j ++) {
res = res * i / j;
if (res > n) return res;
}
return res;
}
bool check(int k) {
ll l = k * 2, r = max(n, l);
while (l < r) {
ll mid = l + r >> 1;
if (C(mid, k) >= n) r = mid;
else l = mid + 1;
}
if (C(r, k) != n) return false;
cout << r * (r + 1) / 2 + k + 1;
return true;
}
int main() {
cin >> n;
for (int k = 16; ; k --)
if (check(k))
break;
return
}