A
link
题目已经说的很明白了,判断即可。
点击查看代码
#include<bits/stdc++.h>using namespace std;int y;signed main(){cin >> y;if(y%4 != 0) cout << 365;else if(y%4 == 0&&y%100 != 0) cout << 366;else if(y%100 == 0&&y%400 != 0) cout << 365;else if(y%400 == 0) cout << 366;return 0;}
B
link
emmm,排序找哪个位置是第二大。
点击查看代码
#include<bits/stdc++.h>using namespace std;int a[105],b[105];signed main(){int n;cin >> n;for(int i = 1;i <= n;++ i)cin >> a[i],b[i] = a[i];sort(a+1,a+1+n);for(int i = 1;i <= n;++ i)if(b[i] == a[n-1]) cout << i;return 0;}
C
link
首先判断一下,如果\(A_i\)的总和还不到\(m\),补贴就可以无限大,因为和\(A_i\)取\(min\),最后不会超过\(A_i\)的和。
剩下的二分答案。对于一个答案\(x\),算出所需付的补贴金额,判断是否\(>m\),如果在\(m\)范围内,可以让\(x\)变大,否则就要变小。
点击查看代码
#include<bits/stdc++.h>#define int long longusing namespace std;int n,m;
int a[200005];
int sum;int check(int x){int res = 0;for(int i = 1;i <= n;++ i)res += min(x,a[i]);return res;
}signed main(){cin >> n >> m;for(int i = 1;i <= n;++ i)cin >> a[i],sum += a[i];if(sum <= m){cout << "infinite";return 0;}int l = 0,r = sum,md;while(l<r){md = (l+r+1)/2;int t = check(md);if(t > m) r = md-1;else l = md;}cout << l;return 0;}
D
link
首先明确一下题意,他说高桥没输过,代表他赢了或平了,在他每次都和前一次出的不一样的情况下,找到赢了的最大数。
考虑\(DP\),设\(f_{i,0/1}\)中\(f_{i,1}\)代表到第\(i\)局中第\(i\)局赢了的赢的最大局数,\(f_{i,0}\)代表到第\(i\)局中第\(i\)局平了的赢的最大局数。
考虑转移。每一个状态都可以从\(i-1\)的所有状态(\(0/1\))转移过来,只要判断这个状态高桥该出什么和前一个的哪一个状态高桥该出什么不一样即可。
if(这一个赢的状态!=上一个赢/平的状态)f[i][1] = max(f[i][1],f[i-1][1/0]+1);
大概这样即可。
点击查看代码
#include<bits/stdc++.h>using namespace std;int n;
char s[200005];
char t[200005][2];
int f[200005][2];char ying(char x){if(x == 'R') return 'P';else if(x == 'P') return 'S';else return 'R';
}signed main(){cin >> n >> s+1;for(int i = 1;i <= n;++ i){t[i][1] = ying(s[i]);t[i][0] = s[i];}int ans = 0,q = 0;for(int i = 1;i <= n;++ i){if(t[i-1][0] != t[i][1])f[i][1] = max(f[i][1],f[i-1][0]+1);if(t[i-1][1] != t[i][0])f[i][0] = max(f[i][0],f[i-1][1]);if(t[i-1][0] != t[i][0])f[i][0] = max(f[i][0],f[i-1][0]);if(t[i-1][1] != t[i][1])f[i][1] = max(f[i][1],f[i-1][1]+1); }cout << max(f[n][1],f[n][0]);return 0;}