A. Unit Array
题意:一个操作可以将-1变成1,问最少操作几次,可以是数组的和>=0,数组的积为正数
思路:求一遍和,然后操作一次+2,求>=0的次数,再判断-1剩下的个数,若是奇数,再操作一次
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
void solve(){
int n;
cin>>n;
int cnt=0;
int ans=0;
for (int i = 0; i <n ; ++i) {
int x;
cin>>x;
ans+=x;
if(x==-1)cnt++;
}
int res=0;
if(ans>=0){
if(cnt%2==1){
res++;
}
}
if(ans<0){
res=(ans-1)/(-2);
if((cnt-res)%2==1){
res++;
}
}
cout<<res<<endl;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
cin>>t;
while (t--){
solve();
}
}
B. Maximum Strength
题意:给l和r,取两个数,使他们的各个位数的之差的和最大,最大是多少
思路:找到第一个不相等的那一位,然后做差,后面的一个取0,一个取9,即ans=abs(a[i]-b[i])+(n-i) * 9
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
void solve(){
string s1,s2;
cin>>s1>>s2;
if(s1.size()<s2.size()){
swap(s1,s2);
}
if(s1.size()==s2.size()){
if(s1<s2)swap(s1,s2);
}
while(s2.size()<s1.size()){
s2="0"+s2;
}
int ans=0;
for (int i = 0; i <s1.size() ; ++i) {
if(s1[i]!=s2[i]){
ans+=s1[i]-s2[i];
ans+=9*s1.size()-(i+1)*9;
break;
}
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
cin>>t;
while (t--){
solve();
}
}
C. Game with Reversing
题意:给定两个字符串,a的操作是改变一个字符串的字符,b的操作是翻转一个字符串,问几次操作可以使两字符串相等。
思路:我们贪心的想,其实我们有两种情况,一种是让他们相等,另一种是互为回文,枚举每一种情况,共四个ans,取最小即可
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
void solve(){
int n;
cin>>n;
string s1;
string s2;
cin>>s1>>s2;
int res1=0,res2=0;
for (int i = 0; i <n ; ++i) {
if(s1[i]!=s2[i]){
res1++;
}
if(s1[i]!=s2[n-i-1])res2++;
}
if(!res1){
cout<<"0\n";
return;
}
if(!res2){
cout<<"2\n";
return;
}
if(res2%2==0) {
res2=res2*2+-1;
}
else{
res2=res2*2;
}
if(res1%2==1) {
res1=res1*2-1;
}
else{
res1=res1*2;
}
cout<<min(res2,res1)<<endl;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
cin>>t;
while (t--){
solve();
}
}
D. Survey in Class
题意:
给定n个区间,你需要选择一些整数,作为集合s,一个区间的得分定义为,对于s中的每一个数,如果在该区间内,得分加一,否则减一,可为负,按照该规则计算每一个区间的得分,问最大分和最小得分的分差最大值是多少?
思路:
比如一个区间是1到5,另一个离他最远的区间4到8,则贡献值就是1到3然后乘以2,即6;那么我们分为三种情况
- 1 当我们计算这个区间的最大贡献时,离他右边最远的那个区间的l,贡献就是 min(r[i],lmax-1)-l[i]+1
- 2 离他左边最远的那个区间的r,贡献就是 r[i]-max(rmin,l[i]-1)
- 3 其次就是有区间在这个区间之内,贡献就是r[i]-l[i]- minlen+1
最后记得乘2;
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
void solve(){
int n,m;
cin>>n>>m;
vector<int>l(n+1),r(n+1);
int lmax=0,rmin=1e9;
int minlen=1e9;
for (int i = 1; i <=n ; ++i) {
cin>>l[i]>>r[i];
lmax=max(l[i],lmax);
rmin=min(r[i],rmin);
minlen=min(minlen,r[i]-l[i]+1);
}
int ans=0;
for (int i = 1; i <=n ; ++i) {
ans= max({ans,r[i]-max(rmin,l[i]-1),min(r[i],lmax-1)-l[i]+1,r[i]-l[i]- minlen+1});
}
cout<<ans*2<<endl;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
cin>>t;
while (t--){
solve();
}
}