这段时间都在cf上vp比赛,所以补的都是cf的题
codeforces923
A
这题我们只需要从1开始遍历到最后一个,找到第一个出现的B和最后一个出现的B,然后把两个位置相减再加一即可
#include <bits/stdc++.h>
using namespace std;
void solve (){
int n;cin>>n;
string s;cin>>s;
int l = 0; //记录第一次出现的位置
int r =0;//记录最后一次出现的位置
int t =0;//指针
while(t != n){
if(s[t] =='B'){
l = t;
break;
}
t++;
}
t =0;
while(t !=n){
if(s[t] =='B')r =t;
t++;
}
cout<<r-l+1<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
B
用一个哈希表存储字母出现的次数,如果与数字的值相同的话,就把它加进字符串中。
#include <bits/stdc++.h>
using namespace std;
void solve (){
int hash[26] = {0};
int n;cin>>n;
string ans;
for(int i =1;i<=n;++i){
int x;cin>>x;
for(int j =0;j<26;++j){
if(hash[j] == x){
hash[j]++;
ans +=char(j + 'a');
break;
}
}
}
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
C
在第一个数组里面找k/2个数 ,第二个数组里面找k/2个数。我们可以用两个map来记录两个数组中的数出现的频率。然后从1开始枚举到k,分别找到a数组里有但b数组里没有的情况和b数组里面没有但a数组里面没有的情况,用cnta和cntb来维护,如果cnta和cntb都小于等于k/2,就满足题意了
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
int a[N] , b[N];
void solve (){
int n,m,k;
cin>>n>>m>>k;
for(int i =1;i<=n;++i)cin>>a[i];
for(int i =1;i<=m;++i)cin>>b[i];
map<int,int>mpa , mpb;
for(int i =1;i<=n;++i){
mpa[a[i]]++;
}
for(int i =1;i<=m;++i)mpb[b[i]]++;
int t =k/2;
int cnta = 0 ,cntb = 0 , cnt =0;
for(int i =1;i<=k;++i){
if(mpa[i] && !mpb[i])cnta++;
if(!mpa[i] && mpb[i])cntb++;
if(!mpa[i] && !mpb[i]){
cout<<"NO"<<'\n';
return;
}
}
if(cnta <=t && cntb <=t)cout<<"YES"<<'\n';
else cout<<"NO"<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
D
开一个新的数组b维护一下出现不同数的位置在哪里,b[r]表示距离r这个点离他最近的一次出现不同的位置,如果这个位置比l小的话,在l和r之间就没有不同的数了
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
int a[N] , b[N];
void solve (){
int n;cin>>n;
for(int i =1;i<=n;++i)cin>>a[i];
for(int i =2;i<=n;++i){
if(a[i] != a[i-1]){
b[i] = i-1; //i-1 和i 不相等
}
else b[i] = b[i-1];
}
//b[i]是存储距离i最近的一次出现不想等的位置在哪里
int q;cin>>q;
while(q--){
int l,r;cin>>l>>r;
if(b[r] >= l)cout<<b[r]<<' '<<r<<'\n';
else cout<<-1<<' '<<-1<<'\n';
}
cout<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
886 div.4
A
传送门:https://www.luogu.com.cn/problem/CF1850A
没什么好说的,略
B
传送门:Ten Words of Wisdom - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
赛时用的vector<pair<int,int>>这种做的,非常麻烦,这里介绍一种简单的
#include <bits/stdc++.h>
using namespace std;
using ll =long long;
void solve (){
int n;cin>>n;
int id = 0 , max = 0 ;
for(int i =1;i<=n;++i){
int x , y;cin>>x>>y;
if(x > 10)continue; //如果大于10的话直接跳过
if(y > max){
max = y;
id = i;
}
}
cout<<id<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
C
传送门:Word on the Paper - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题也很简单,只要s[i][j] != '.' 的话,把它加到字符串中就行了
#include <bits/stdc++.h>
using namespace std;
using ll =long long;
char s[9][9];
void solve (){
for(int i =1;i<=8;++i)
for(int j =1;j<=8;++j)
cin>>s[i][j];
string ans;
for(int i =1;i<=8;++i){
for(int j =1;j<=8;++j){
if(s[i][j] != '.')ans +=s[i][j];
}
}
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
D
传送门:Balanced Round - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题考虑贪心的思想,将序列分成几块,每块之间都满足题意,然后我们找到最大的块,再用序列长度减去最大的块。
#include <bits/stdc++.h>
using namespace std;
using ll =long long;
const int N =2e5 +9;
int a[N];
void solve (){
int n , k;cin>>n>>k;
for(int i =1;i<=n;++i)cin>>a[i];
sort(a+1 , a+1+n);
int cnt = 1;
int ans =0;
for(int i =2;i<=n;++i){
if(a[i] - a[i-1] > k){
ans = max(ans , cnt);
cnt = 1;
}
else cnt++;
}
ans = max(ans ,cnt);
cout<<n - ans<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
E
这题可以使用数学推导,有点麻烦,就不说这个方法了,赛后才知道可以使用二分去做。那么为什么可以使用二分呢?我们可以看到,w越大,他的面积就越大,是一个递增的关系,这种我们可以使用二分答案去做。
#include <bits/stdc++.h>
using namespace std;
using ll =long long;
const int N =2e5 +9;
ll a[N];
ll n,c;
bool check(ll x){
ll sum=0;
for(int i=1;i<=n;++i){
sum+=(2*x+a[i])*(2*x+a[i]);
if(sum>c)return false;
}
return true;
}
void solve (){
cin>>n>>c;
for(int i =1;i<=n;++i)cin>>a[i];
sort(a+1 , a+1+n);
ll l = 0 , r =1e9;
while(l +1 < r){
ll mid = (r+l)>>1;
if(check(mid))l = mid;
else r = mid;
}
if(check(l))cout<<l<<'\n';
else cout<<r<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
F
传送门:We Were Both Children - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
我们需要记录最初从1到每个坑里面都有几只青蛙,然后从1开始让每个坑里面的青蛙跳,一直跳到不能跳为止(就是 <= n),之后再看坑里面都容纳了多少只青蛙,拿出最大的。
#include <bits/stdc++.h>
using namespace std;
using ll =long long;
const int N =2e5 +9;
int a[N] , num[N],res[N];
void solve (){
memset(num , 0 ,sizeof(num));
memset(res , 0 ,sizeof(res));
int n;cin>>n;
for(int i =1;i<=n;++i){
int x;cin>>x;
if(x <= n )num[x]++;
}
int ans =0;
for(int i =1;i<=n;++i){
for(int j = 1;j*i <=n;++j){
res[i * j] += num[i];
}
}
for(int i =1;i<=n;++i){
ans = max(ans , res[i]);
}
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(),cout.tie(0),cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}
剩下两道题G和H,下次再说