比赛靠手机码代码真累QAQ
B-减成一
1)知识点
- 就是一道简单的动态规划。
2)看题目
- 就是你每次都可以让一个区间数字都-1,求最少几次全变1。
3)算法分析
- 一开始我以为不是连续区间,还直接就排个序来搞了。但是看到连续区间的时候我就发现这一定是个dp。
- 说到dp:动态规划最重要的就是递推和dp数组的含义。
- 首先我们讲一下dp数组的含义:这里重要的是数的位置。所以dp数组就是一个一维数组:dp[位置] = 最小次数。
- 然后是递推:
- 首先很简单,如果我们这一位比上一位要大,那么说明要比上一位要多操作x次(x为前后的差值)。
- 如果后面比前面小呢,就不用增加操作次数,因为可以在前面操作的时候就操作掉ta了。
- 就是这样,这是一道十分简单的动态规划。
4)算法操作
- 就先写一下dp数组的含义:
int dp[MAX];//dp[位置] = 最小次数 - 然后是我们的递推公式:
dp[0] = 0; info[0] = 1; for (int i = 1; i <= n; i++) { if (info[i] >= info[i - 1]) dp[i] = dp[i - 1] + info[i] - info[i - 1]; else dp[i] = dp[i - 1]; }
5)打代码
- 首先输入数据。
- 然后按照上面的dp就好了。
- 下面全代码~
AC代码
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 1e5 + 7;
int info[MAX], dp[MAX];
int main() {
int T; cin >> T;
while (T--) {
int n; cin >> n;
for (int i = 1; i <= n; i++)
cin >> info[i];
dp[0] = 0; info[0] = 1;
for (int i = 1; i <= n; i++) {
if (info[i] >= info[i - 1])
dp[i] = dp[i - 1] + info[i] - info[i - 1];
else
dp[i] = dp[i - 1];
}
cout << dp[n] << endl;
}
return 0;
}
C-面积
啊这
签到题我懂的。
正方向是边长平方,圆是πr2就不用我说了吧。
py再见
AC代码
T = int(input())
for _ in range(T):
a = int(input())
r = a / 2
ans = a * a + 2 * 3.14 * r * r
print("%.2f" % ans)
E-赛马
1)知识点
这道题是二分,并且可以用STL简化代码。
2)看题目
题目的意思就是叫我们田忌赛马,求最大能赢的比赛。
3)算法分析
- 田忌赛马我们都懂,其实就是选择比对方的马大仅仅一号的马去比赛。
- 所以我们先把我们的马保存下来,然后排个序(这里阔以用STL的multiset,放入自动排序,但是会慢很多),就可以二分找答案了。
- 每次选比这个马大一号的就行了。
4)算法操作
- 我们用multiset保存数据(可自动排序):
for(int i = 0 ; i < n ;++i){ int x; cin >> x; q.insert(x); } - 然后就可以去二分找答案啦:
int ans = 0; for(int i = 0 ; i < n ;++i){ int x; cin >> x; auto it = upper_bound(q.begin(), q.end(), x); if(it != q.end()){ ++ans; q.erase(it); } }
5)打代码
- 首先STL保存数据。
- 然后按上面二分找答案。
- 下面全代码~
AC代码
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
multiset<int> q;
int main(){
int T; cin >> T;
while(T--){
q.clear();
int n; cin >> n;
for(int i = 0 ; i < n ;++i){
int x; cin >> x;
q.insert(x);
}
int ans = 0;
for(int i = 0 ; i < n ;++i){
int x; cin >> x;
auto it = upper_bound(q.begin(), q.end(), x);
if(it != q.end()){
++ans;
q.erase(it);
}
}
cout << ans << endl;
}
}
F-三角形
1)知识点
- 递推,就是递推。
2)看题目
- 题目说就是把一个长度为a的可以最多分成几个棒子,使其全不可组成三角形。
3)算法分析
- 首先最小的是1,所以先裁出两个1,然后最小肯定两边之和,就是1 + 1。
- 同理往后,现在有1,1,2,下一个就要1 + 2。我们就看出了这就是个斐波那契。
4)算法操作
- 先初始化斐波那契数列,因为很大,开一个__int128:
for(int i = 3 ; i < 1005 ; ++i) fib[i] = fib[i-1]+fib[i-2];
- 就拿出来判断呗:
for(int i = 3 ; i < 1005 ;++i){ if(fib[i]-1 > a){ ans = i-3; break; } }
5)打代码
- 先初始化斐波那契序列。
- 然后遍历查找就好了。
- 下面全代码~
AC代码
#include <iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
const int maxn = 100005;
__int128 fib[1005] = {0,1,1};
int main(){
js;
for(int i = 3 ; i < 1005 ; ++i)
fib[i] = fib[i-1]+fib[i-2];
int T; cin >> T;
while(T--){
ull a; cin >> a;
if(a < 3){
cout << a << endl;
continue;
}
ll ans;
for(int i = 3 ; i < 1005 ;++i){
if(fib[i]-1 > a){
ans = i-3;
break;
}
}
cout << ans << endl;
}
}
H-直线
啊这
你高中学过。
证明我就不证了。看我代码
AC代码
T = int(input()) for _ in range(T): n = int(input()) ans = n * (n - 1) // 2 print(ans)
J-最大值
1)知识点
- 就是kmp嘛
2)看题目
- 题目叫你找一个非前缀的最大的匹配串,可以和前缀最大匹配多长。
3)算法分析
- 其实就是个kmp都能看出来,但是怎么kmp呢?
- 我们kmp其实就是一个对着匹配串原串往后匹配的过程。
- 然后呢我们就可以把原串分为一个原串,一个非前缀串(就是原串去掉第一个字符)。
- 进行一遍匹配,在途中保存最大的匹配长度就好了。
4)算法操作
- 我们的next数组我相信大家都没有问题:
void getnext(char b[]) { int i, j, len = strlen(b); Next[0] = -1; for(i = 0, j = -1; i < len;) if(j == -1 || b[i] == b[j]){ ++i; ++j; if(b[i] != b[j]) Next[i] = j; else Next[i] = Next[j]; } else j = Next[j]; } - 然后kmp也就是正常匹配,也就是加了一个读最大值而已:
void kmp(char a[],char b[]) { getnext(b); int n = strlen(a); int len = strlen(b); for(int i = 0, j = 0; i < n && j < len;) { if(j == -1 || a[i] == b[j]) { i++, j++; } else j = Next[j], cnt = 0; ans = max(j, ans);//读取最大值 } }
5)打代码
- 先就是输入。
- 然后按上面kmp一下就好了
- 下面全代码~
AC代码
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
const int maxn = 100005;
int cnt = 0, ans = 0;
int Next[maxn];
char a[maxn], b[maxn];
void getnext(char b[]) {
int i, j, len = strlen(b);
Next[0] = -1;
for(i = 0, j = -1; i < len;)
if(j == -1 || b[i] == b[j]){
++i; ++j;
if(b[i] != b[j]) Next[i] = j;
else Next[i] = Next[j];
}
else j = Next[j];
}
void kmp(char a[],char b[]) {
getnext(b);
int n = strlen(a);
int len = strlen(b);
for(int i = 0, j = 0; i < n && j < len;) {
if(j == -1 || a[i] == b[j]) {
i++, j++;
}
else j = Next[j], cnt = 0;
ans = max(j, ans);
}
}
int main() {
IOS;
int n; cin >> n;
while (n--) {
ans = 0;
cin >> b;
strcpy(a, b + 1);
kmp(a, b);
cout << ans << endl;
}
}
京公网安备 11010502036488号