分数分布情况:
题目详解:
A - Count Down
Print all non-negative integers less than or equal to N in descending order.
题目大意:降序打印所有非负且小于等于N的数字
解题思路:设置一个变量将他自减并打印出来即可
AC代码:
#include <iostream>
using namespace std;
int main()
{
int N;
cin >> N;
for (int i = N; i >= 0; i--)
{
cout << i << endl;
}
}
B - Sandwich Number
题目大意:输入一个字符串s判断s是否符合以下三个条件?
1.以大写字母开头
2.还没到中间包含一个六位数的数字x。其大小在
3.以大写字母结束
解题思路:读取一个字符串s的首尾字符,在判断中间的数字是否符合要求即可
#include <iostream>
using namespace std;
int main()
{
string S;
cin >> S;
if (S.length() != 8)
{
cout << "No";
return 0;
}
if (S[1] <= '0' || S[1] > '9')
{
cout << "No";
return 0;
}
if (S[0] < 'A' || S[0] > 'Z' || S[S.length() - 1] < 'A' || S[S.length() - 1] > 'Z')
{
cout << "No";
return 0;
}
for (long unsigned int i = 2; i < 7; i++)
{
if (S[i] < '0' || S[i] > '9')
{
cout << "No";
return 0;
}
}
cout << "Yes";
return 0;
}
C - Circular Playlist
题目大意:有一个播放器里面一共有n首歌。给定每一首歌的长度,每首歌的播放是互斥的并且一首播完立即播下一首。那么在一个给定的T时间之后,播放到哪一首歌了?这首歌已经播放了几秒?
解题思路:题目的描述很容易让人想到取余运算。
那么我的思路是首先观察题目给的数据
我们可以知道T是播放时间的累计,而且歌曲列表是循环的
所以把给定的时间T与歌曲总时长sum取余得到的数就是最后一次循环正在播放的歌曲的净时间。那么只需要判断在最后一次停在哪里即可,把时间从头开始累加起来就行,把时间从头开始累加起来就行,一旦这个数字超过T%sum就证明正在播放这一首歌,最后再相减就可以得到这首歌已经播放的时间。
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n, t, sum = 0, tmp = 0, a[100010];
cin >> n >> t;
for (int i = 0; i < n; i++)
{
cin >> a[i];
sum += a[i];
}
for (int i = 0; i < n; i++)
{
tmp += a[i];
if (tmp > t % sum)
{
cout << i+1 << endl;
cout << t % sum - (tmp - a[i]) << endl;
return 0;
}
}
return 0;
}
D - Max Multiple
题目大意:
解题思路:我们可以设假设dp[i][j][k]表示从前 i个数取出 j个数,当这些数和d取余的结果为k时和的最大值。状态转移方程就考虑第 i个数选或不选即可。
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1e2 + 10;
long long dp[MAXN][MAXN][MAXN], a[MAXN];
int main()
{
int N, K, D;
cin >> N >> K >> D;
for (int i = 0; i < N; i++)
{
cin >> a[i];
}
memset(dp, -1, sizeof(dp));
dp[0][0][0] = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j <= K; j++)
for (int k = 0; k < D; k++)
{
if (dp[i][j][k] == -1)
{
continue;
}
dp[i + 1][j][k] = max(dp[i][j][k], dp[i + 1][j][k]); // 第二种情况
if (j < K)
{
dp[i + 1][j + 1][(k + a[i]) % D] = max(dp[i + 1][j + 1][(k + a[i]) % D], dp[i][j][k] + a[i]);
}
}
cout << dp[N][K][0];
return 0;
}
E - Least Elements
题目大意:给你一个整数数组 A,求每段长为 M的数列中前 K小的数的和
解题思路:这应该是一道滑动窗口的题目可以拿一个数据结构维护这前k小的数。当窗口滑动的时候,这里面有一些数可能因为不在窗口里而被踢掉,而有一些可能因为窗口新加进来的数更小而被踢掉(但被踢掉的数还可能拿回来),因此我们把这个窗口里的m个数用两个数据结构维护。第一个数据结构维护这 m个数中前 k小的数,而第二个数据结构维护剩下的m−k个数。第一个数据结构要求能踢掉指定元素(不在窗口内的),还要查询其最大值(与新加进来的数比较),然后实时保证其元素个数为k。而第二个数据结构则仅要求查询其最小值(踢掉的话可以在查的时候看下标是不是合法的)因此第一个数据结构可以用 集合,第二个就用优先队列。
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
int n, m, k;
cin >> n >> m >> k;
vector<int> a(n);
for(auto &i : a)
cin >> i;
priority_queue<pair<int, int>> val;
set<pair<int, int>> pos;
LL ans = 0;
for(int i = 0; i < m - 1; ++ i){
val.push({-a[i], i});
}
for(int i = m - 1; i < n; ++ i){
int l = i - m + 1;
if (l > 0){
auto it = pos.find({a[l - 1], -(l - 1)});
if (it != pos.end()){
pos.erase(it);
ans -= a[l - 1];
}
}
val.push({-a[i], i});
while(pos.size() < k){
auto tmp = val.top();
if (tmp.second >= l){
pos.insert({-tmp.first, -tmp.second});
ans += -tmp.first;
}
val.pop();
}
while(!val.empty()){
auto tmp = val.top();
if (tmp.second >= l && -tmp.first < pos.rbegin() -> first){
val.pop();
auto it = prev(pos.end());
val.push({-it->first, -it->second});
ans -= it->first;
pos.erase(it);
pos.insert({-tmp.first, -tmp.second});
ans += -tmp.first;
}else if (tmp.second < l)
val.pop();
else
break;
}
cout << ans << ' ';
}
return 0;
}
F - Xor Minimization
题目大意:给一个n个元素的序列,现在进行一次操作,任选一个数x,对每一个元素,都异或x。问操作后序列中的最大值的最小是多少?
解题思路:这个题目看第一眼时我想到了二分查找,因为他有一个最小化最大值,后来仔细想了想,发现这题其实是一道字典树的题目,那问题就迎刃而解了。(关于字典树是什么)
#include <bits/stdc++.h>
using namespace std;
int M=1e5*5;
int ch[M*30][2],tot;
int dfs(int now,int dep) {
if(dep==-1)return 0;
if(ch[now][0]==0)return dfs(ch[now][1],dep-1);
if(ch[now][1]==0)return dfs(ch[now][0],dep-1);
return min(dfs(ch[now][0],dep-1),dfs(ch[now][1],dep-1))+(1<<dep);
}
int main() {
int n;
cin >> n;
for(int i=1;i<=n;i++) {
int p=0;
int x;
cin >> x;
for(int j=29;j>=0;j--) {
int v=x>>j&1;
if(ch[p][v]==0)ch[p][v]=++tot;
p=ch[p][v];
}
}
cout << dfs(0,29) << endl;
return 0;
}
G和EX等我容先学学再写()