第一题:信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)
http://ybt.ssoier.cn:8088/problem_show.php?pid=2086
思路
一共有两种情况。第一种:如果 a == 1,不管 b 是多大,答案始终为一,直接输出即可
if(a == 1) { cout << 1 << endl; return 0; }第二种:a >= 2,int 类型能表示的最大数为 2^31 - 1,所以对于 a 来说,最多暴力计算 31 次答案就会超过 int 值,所以我们只需要暴力计算即可,无需优化
100分代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e9;
signed main() {
int a, b;
cin >> a >> b;
if(a == 1) {
cout << 1 << endl;
return 0;
}
int ans = 1;
for(int i = 1; i <= b; i++){
ans *= a;
if(ans > maxn){
cout << -1 << endl;
return 0; // 提前退出
}
}
cout << ans << endl;
return 0;
}
第二题:信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)
http://ybt.ssoier.cn:8088/problem_show.php?pid=2087
思路
公式变形:
,
可以得到:
因为:
, 所以:
那么:
又因为:
, 那么:
那么:
由题,我们知道 p 和 q 都是 n 的因子,于是我们只需要枚举其中较小的一个因子 p 即可,另外一个因子即为 n / p
此方法枚举可拿60分
60分代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e9;
void solve() {
int n, e, d;
cin >> n >> e >> d;
for(int i = 1; i <= sqrt(n); i++) {
if(n % i == 0 && i + n / i == n - e * d + 2) {
cout << i << " " << n / i << endl;
return;
}
}
cout << "NO" << endl;
}
signed main() {
int _; cin >> _;
while(_--) solve();
return 0;
}
由上面,
,其中,n e d 均为已知数
令
则
则
,其中,n m 均为已知数
则题目变为解一元二次方程
要求:delta >= 0 且解为整数
TIPS:输入输出使用 scanf, printf
100分代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e9;
void solve() {
int n, e, d;
scanf("%lld %lld %lld", &n, &e, &d);
int m = n - e * d + 2;
int delta = m * m - 4 * n;
int res = sqrt(delta);
if(delta < 0 || res * res != delta) {
puts("NO");
return ;
}
if((m + res) % 2 == 1) {
puts("NO");
return ;
}
printf("%lld %lld\n", (m - res) / 2, (m + res) / 2);
}
signed main() {
int _; cin >> _;
while(_--) solve();
return 0;
}
第三题:信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)
http://ybt.ssoier.cn:8088/problem_show.php?pid=2088
思路
第四题:
信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)
http://ybt.ssoier.cn:8088/problem_show.php?pid=2089
思路
动态规划题
f[i][j] 表示以第 i 个点结尾,添加了 j 个点的最大长度
先将点集进行从小到大排序,第 i 个点可由第 i - 1 个点转移,假设两个点之间的距离为 len,则需要添加 len - 1 个点就可以满足题设条件
需要注意的是序列要满足横纵坐标均不递减
100分代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int, int>
const int maxn = 1e9;
int f[510][110];
vector<PII> res;
int n, k;
int get(PII a, PII b) {
return abs(a.first - b.first) + abs(a.second - b.second);
}
int check(PII a, PII b) {
return a.first >= b.first && a.second >= b.second;
}
void solve() {
cin >> n >> k;
res.push_back({0, 0});
for(int i = 0; i < n; i++) {
int a, b;
cin >> a >> b;
res.push_back({a, b});
}
sort(res.begin(), res.end());
for(int i = 1; i <= n; i++){
for(int j = 0; j <= k; j++) f[i][j] = j + 1;
}
int ans = -1;
for(int i = 1; i <= n; i++){
for(int j = 1; j < i; j++){
int len = get(res[i], res[j]) - 1;
if(!check(res[i], res[j])) continue;
if(len > k) continue;
for(int g = len; g <= k; g++) {
f[i][g] = max(f[i][g], f[j][g - len] + len + 1);
ans = max(ans, f[i][g] + k - g);
}
}
}
cout << ans << endl;
}
signed main() {
int _ = 1;// cin >> _;
while(_--) solve();
return 0;
}
2086

被折叠的 条评论
为什么被折叠?



