A
思路:贪心。将数列倒序分别计算两人的和即可。
#include <bits/stdc++.h>
using namespace std;
int a[110];
void solve()
{
int n;
cin>>n;
int sum1=0,sum2=0;
int flag=1;
for (int i=1;i<=n;i++) cin>>a[i];
for (int i=n;i>=1;i--){
if(flag==1){
sum1+=a[i];
flag=0;
}
else {
sum2+=a[i];
flag=1;
}
}
if(sum1>sum2){
cout<<"Alice"<<endl;
}
else {
cout<<"Bob"<<endl;
}
}
int main()
{
int t;
cin>>t;
while(t--){
solve();
}
}
B.
思路:因为只能选择一个区间,且要小于全体区间,所以只需要判断其首尾是否为最小和最大即可。若都不是,则不能。否则能。
#include <bits/stdc++.h>
using namespace std;
int a[200010],b[200010];
void solve()
{
int n;
cin>>n;
for (int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+n+1);
if(a[1]!=b[1] &&a[n]!=b[n]){
cout<<"NO"<<endl;
return ;
}
cout<<"YES"<<endl;
}
int main()
{
int t;
cin>>t;
while(t--){
solve();
}
}
C.
思路:双指针。通过左右指针通过分类讨论进指针的移动即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int main()
{
int n,k;
cin>>n>>k;
string s;
cin>>s;
int pos=0;
for (int i=0;i<n;i++){
if(s[i]=='I'){
pos=i;
break;
}
}
int l=pos-1,r=pos+1;
for (int i=1;i<=k;i++){
string s1;
cin>>s1;
if(s1=="backspace"){
if(s[l]=='(' && s[r]==')'){
l--,r++;
}
else {
if(l>=0){
l--;
}
}
}
else {
if(s[r]==')' ||s[r]=='('){
r++; }
}
for (int i=0;i<=l;i++){cout<<s[i];}
cout<<'I';
for (int i=r;i<n;i++){
cout<<s[i];
}
}
}
D
思路:双指针。当左右操作可以将指针移动并将原字符串重新赋值即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int main()
{
int n,k;
cin>>n>>k;
string s;
cin>>s;
s=" "+s;
int pos=0;
for (int i=1;i<=n;i++){
if(s[i]=='I'){
pos=i;
break;
}
}
int l=pos-1,r=pos+1;
for (int i=1;i<=k;i++){
string s1;
cin>>s1;
if(s1=="backspace"){
if(s[l]=='(' && s[r]==')'){
l--,r++;
}
else {
if(l>=1){
l--;
}
}
}
else if(s1=="delete"){
if(s[r]==')' || s[r]=='('){
r++;
}
}
else if (s1=="<-"){
if(l!=0){
r--;
s[r]=s[l];
l--;
}
}
else {
if(r!=n+1)
{
l++;
s[l]=s[r];
r++;
}
}
}
for (int i=1;i<=l;i++)cout<<s[i];
cout<<'I';
for (int i=r;i<=n;i++){
cout<<s[i];
}
}
E.
思路:本题要求构造一个a和b数组相加为不递减序列,并且b数组的极差为最小的b数组。
可以通过遍历a数组并且每次更新最大值,并使得b数组为这个·最大值和当前a值的差。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[200010];
signed main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++){
cin>>a[i];
}
int maxn=a[1];
for (int i=1;i<=n;i++){
maxn=max(maxn,a[i]);
cout<<maxn-a[i]<<" ";
}
}
F.
思路:位运算,贪心。按位与的运算结果必然最小,所以按位与的段要尽可能的小。
而异或和按位或都是大于等于原来的结果。所以通过枚举来判断间隔点。并通过前后缀来优化。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[200010],b[200010],c[200010];
signed main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++){
cin>>a[i];
}
for (int i=1;i<=n;i++){
b[i]=b[i-1]^a[i];
}
for (int i=n-1;i>=1;i--){
c[i]=c[i+1]|a[i];
}
int ans=0;
for (int i=1;i<n-1;i++){
ans=max(ans,b[i]+c[i+1]+a[n]);
}
cout<<ans;
}