Codeforces Round #849 (Div. 4)
A. Codeforces Checking
大水题,只需要在规定字符串中查找即可
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll x[maxn];
ll n,d,t;
void solve()
{
char c;
cin>>c;
string s="codeforces";
if(s.find(c)!=string::npos)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
}
B. Following Directions
由于需要执行的步骤不长,直接检验每执行一次指令之后所移动到的位置是否是目标点即可。
```cpp
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t;
void solve()
{
int x=0,y=0;
cin>>n;
string s;
cin>>s;
bool flag=0;
for(int i=0;i<s.length();i++)
{
if(s[i]=='R')
{
x++;
}
else if(s[i]=='L')
{
x--;
}
else if(s[i]=='U')
{
y++;
}
else
{
y--;
}
if(x==1&&y==1)
{
flag=1;
break;
}
}
if(flag)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
}
C. Prepend and Append
由于每次操作都是在顶端与末端插入1或0,那么我们用两个指针分别从首部以及末尾同时进行查找,直到剩余长度为1或者两个指针的指向相同止
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t;
void solve()
{
cin>>n;
string s;
cin>>s;
int l=0,r=n-1;
ll ans=0;
while(l<r)
{
int x=s[l]-'0';int y=s[r]-'0';
if(x^y)
{
ans+=2;
l++;
r--;
}
else
{
break;
}
}
cout<<n-ans<<endl;
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
}
D. Distinct Split
该题要求我们将一个字符串分成两个部分,然后求出每个子串中去重之后还剩余的长度,相加得最大值。只需用两个set容器来进行记录,一个从开头到末尾,一个反之,枚举求最大值即可。
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t,c;
ll a[maxn];
ll b[maxn];
void solve()
{
cin>>n;
string s,tmp;
cin>>s;
set<char>num1;
set<char>num2;
ll ans=0;
for(int i=0;i<n;i++)
{
num1.insert(s[i]);
a[i]=num1.size();
}
for(int i=n-1;i>=0;i--)
{
num2.insert(s[i]);
b[i]=num2.size();
}
for(int i=0;i<n-1;i++)
{
ans=max(ans,a[i]+b[i+1]);
}
cout<<ans<<endl;
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
}
E. Negatives and Positives
每次我们可以选择两个相邻的数并对他们进行取反,然后求数组和的最大值。实际上,我们只需统计负数的个数即可,如果负数的个数是偶数,那么我们可以将负数全部翻转成正数,此时值最大;如果负数的个数是奇数,无论我们怎么翻转,都会有一个负数存在,不妨将绝对值最小的数变成负数,此时得最大值。
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t,c;
void solve()
{
cin>>n;
ll ans=0;
ll cnt=0;
vector<int>x;
for(int i=0;i<n;i++)
{
int tmp;
cin>>tmp;
if(tmp<0) cnt++;
ans+=abs(tmp);
x.emplace_back(abs(tmp));
}
sort(x.begin(),x.end());
if(cnt%2)
{
ans-=2*x[0];
}
cout<<ans<<endl;
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
}
F. Range Update Point Query
当输入1的时候,我们需要对l~r区间的数进行修改,将他们修改成为自身各位数字之和,然而当数小于10的时候,无论怎么修改他都是自己本身,所以,我们只需要记录大于10的数字所在的位置即可,然后再对指定的区间位置进行修改,如果该数修改后小于10,那么便将他的位置记录从记录数组中删去,以减少运算次数。这里我们记录数组用容器set,因为vecor的删除时间复杂度是O(N),会TLE。
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t,q;
ll a[maxn];
int x[maxn];
int getsum(int tmp)
{
int sum=0;
while(tmp)
{
sum+=(tmp%10);
tmp/=10;
}
return sum;
}
void solve()
{
cin>>n>>q;
set<int>lo;
for(int i=1;i<=n;i++)
{
cin>>x[i];
if(x[i]>=10)
{
lo.insert(i);
}
}
for(int i=1;i<=q;i++)
{
int type;
cin>>type;
if(type==2)
{
int l;
cin>>l;
cout<<x[l]<<endl;
}
else
{
int tmp1,tmp2;
cin>>tmp1>>tmp2;
vector<int>l;
for(set<int>::iterator it=lo.lower_bound(tmp1);it!=lo.end()&&(*it)<=tmp2;it++)
{
l.emplace_back(*it);
}
for(int j=0;j<l.size();j++)
{
x[l[j]]=getsum(x[l[j]]);
if(x[l[j]]<10)
{
lo.erase(l[j]);
}
}
}
}
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
}
G1. Teleporters (Easy Version)
该题要我们求出,如何用限定的钱去使用最大数量的传送器,左右移动一格会消耗我们1块钱,使用某个点的传送器时会消耗a[i]块钱,由于使用过后我们就会被传送会0点,故只需要将到达每个位置所花的钱与使用该点传送器的钱相加进行排序,遍历即可。
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t,c;
ll x[maxn];
void solve()
{
cin>>n>>c;
for(int i=1;i<=n;i++)
{
cin>>x[i];
x[i]+=i;
}
sort(x+1,x+1+n);
ll ans=0;
for(int i=1;i<=n;i++)
{
if(c>=x[i])
{
ans++;
c-=x[i];
}
else
{
break;
}
}
cout<<ans<<endl;
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
G2. Teleporters (Hard Version)
该题与上一题不同的是,每次使用之后我们可以自主选择自己的降落位置到0或者n+1,这样的话,我们用一个对组来记录每个点的最小花费以及从0出发并且使用的花费,之后我们进行枚举,从各个点开始出发,来找出所能使用的最大值。
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define ll long long
#define P pair<ll,ll>
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,t,c;
P x[maxn];
ll sum[maxn];
void solve()
{
cin>>n>>c;
for(int i=1;i<=n;i++)
{
cin>>x[i].second;
x[i].first=min(x[i].second+i,x[i].second+n+1-i);
x[i].second+=i;
}
sort(x+1,x+n+1);
for(int i=1;i<=n;i++)
{
sum[i]=sum[i-1]+x[i].first;
}
ll ans=0;
for(int i=1;i<=n;i++)
{
if(x[i].second<=c)
{
ll l=0,r=n,mid;
while(l<r)
{
mid=(l+1+r)/2;
ll val=sum[mid];
if(mid>=i)
{
val-=x[i].first;
}
if(val+x[i].second<=c)
{
l=mid;
}
else
{
r=mid-1;
}
}
ans=max(ans,l+(l<i));
}
}
cout<<ans<<endl;
}
int main()
{
cin>>t;
while(t--)
{
solve();
}
}