
前言
这场没打,是后面补的,原本是打算把C补出来再写题解的,结果一直没补出来,所以就只能先出A,B的题解,后面看还会不会补了
题解部分
给你一个字符串和一个H行W列的表格,起点为第一行第一列,如果当前字符是D就向下走一格,如果当前字符是R就向右走一格,最终走到右下角。但是当前字符有些位置是?,请你在?位置填上D或者R使得最终能走到终点,并且计算所有满足条件的路线所覆盖的格子个数,注意一定存在满足条件的路线
这道题刚开始我的思路是想找一个规律的,但是很明显这并不现实,这其实就是一个模拟。
我们要计算覆盖的路线,但是我们又肯定不能全部路线走一遍,在纸上模拟一下就能发现,对于所有能够到达终点的路线,由于D和R的数量是相等的,所以我的改动就相当于向下一格,然后再向右走那么多步,也就是说,所有路线覆盖的格子是联通的
既然如此,我们就能找到每一行最左边的覆盖位置以及最右边的覆盖位置。至于怎么找,如果我尽量填R,那么得到的肯定是每一行最右边的覆盖位置。同理,如果我尽量填D,那么得到的肯定是每一行的最左边的覆盖位置。由此我们就能算出所有路线的覆盖格子个数
代码如下:
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lowbit(x) x&(-x)
const int MOD=1e9+7;
const int N=1000100;
int a[N];
void solve() {
init();
int h,w;
cin>>h>>w;
string s;
cin>>s;
int ans=0;
int row=1;
int col=1;
map<int,int>left,right;
int hh=h-1,ww=w-1;
int num1=0,num2=0;
for(int i=0;i<h+w-2;i++) hh -= (s[i]=='D'),ww -= (s[i]=='R');
for(int i=0;i<h+w-2;i++) {//尽可能向右策略
if(s[i]=='D') {
right[row]=col;
row++;
}
else if(s[i]=='R') col++;
else {
if(num2 < ww) {
num2++;
col++;
}
else {
right[row]=col;
row++;
}
}
}
right[row]=col;
num1=0;
num2=0;
row=1;
col=1;
left[row]=col;
for(int i=0;i<h+w-2;i++) {//尽可能向下策略
if(s[i]=='D') row++,left[row]=col;
else if(s[i]=='R') col++;
else {
if(num1 < hh) {
num1++;
row++;
left[row]=col;
}
else col++;
}
}
for(int i=1;i<=h;i++) ans+=right[i] - left[i] + 1;
cout<<ans<<"\n";
}
signed main() {
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout.tie(0);
//cout<<prime[cnt-1]<<"\n";
//for(int i=1;i<=cnt;i++) cout<<prime[i]<<"\n";
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}
给你一个序列,要求你找到所有的子序列中,数字大于该子序列平均值的个数最大值
我们要大于平均值的个数最大值,可以捋一下以下两点:1.添加一个比当前平均值小的数,平均值变小。2.添加一个比当前平均值大的数,平均值变大
那可能有的人就觉得说,这不是显然的吗。但很多时候就是这种显然的东西衍生出很难的题。 按照加粗的条件,首先我们肯定先放一个最小的数字在里面,这个时候平均值就是这个最小的数字
然后我是不是要增加大于平均值的元素数量,那请问我是从小到大加还是从大到小加。那肯定是从大到小加。因为我添加大于平均值的元素数量的时候,平均值也会跟着变大,那么前面的值就容易变成小于平均值,所以我们要从大到小添加大于平均值的元素
那一直添加到下一个数比平均值小怎么办,这个时候就结束了吗,是不是不一定。那我们就要继续添加一个最小的未添加的元素,然后重复这个过程
所以我们直接排序,重复以上过程即可
代码如下:
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lowbit(x) x&(-x)
const int MOD=1e9+7;
const int N=1000100;
int a[N];
void solve() {
init();
int n;
cin>>n;
int sum=0;
for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
sort(a+1,a+n+1);
priority_queue<int ,vector<int> > q;
int zhi=0;
for(int i=1;i<=n;i++) {
if(n * a[i] > sum) q.push(a[i]);
else zhi=i;
}
int num=0;
int maxvalue=q.size();
while(!q.empty()) {
num++;
sum-=q.top();
q.pop();
while(zhi >= 1 && (n - num) * a[zhi] > sum) q.push(a[zhi]),zhi--;
maxvalue=max(maxvalue,(int)q.size());
}
cout<<maxvalue<<"\n";
}
signed main() {
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout.tie(0);
//cout<<prime[cnt-1]<<"\n";
//for(int i=1;i<=cnt;i++) cout<<prime[i]<<"\n";
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}