目录
B. Erase First or Second Letter
A. Least Product
题目大意:
给你一个数组,让你求出数组乘积的最小值。另外你可以执行多次操作(将数组中任意一个数变成0),输出你将数组乘积变成最小执行的操作次数。
题解:
因为操作只能将数字变成0,所以在输入过程中,先判断原数组有没有0,如果有0直接输出操作次数0,如果没有0,则判断负数个数,如果为奇数则不用操作(即操作次数0),如果为偶数,则将任意一个数变成0即可,操作次数1,正数不用考虑。
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl "\n";
int aa[200100];
void solve()
{
int n,b=0,flag=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>aa[i];
if(aa[i]<0)
b++;
if(aa[i]==0)
flag=1;
}
if(flag){
cout<<0<<endl;
}
if(b%2){
cout<<0<<endl;
}
else{
cout<<1<<endl;
cout<<1<<" "<<0<<endl;
}
return ;
}
signed main()
{
IOS
int t=1;
cin>>t;
while(t--)
solve();
return 0;
}
B. Erase First or Second Letter
题目大意:
给你一个字符串,并且你有两种操作:1.将首个字符删除。2.将第二个字符删除。操作次数不限,在你所有的操作中,一共能弄出多少种不同的非空字符串。
题解:
因为操作是从头进行,所以可以得出一个结论:前面出现过的字符,后面再出现,它之后的操作都和前者是重复的,所以只需要判断从头到尾一共出现多少不同的字符,并且每次出现一个不同的,就将其所在的位置和后面的字符数量相加。
AC代码:
#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl "\n";
int a[200100];
void solve()
{
int n,ans=0,sum=0;
cin>>n;
string x;
cin>>x;
map<char,int>m;
for(int i=0;i<x.size();i++){
if(!m[x[i]]){
sum+=n-i;
}
m[x[i]]++;
}
cout<<sum<<endl;
return ;
}
signed main()
{
IOS
int t=1;
cin>>t;
while(t--)
solve();
return 0;
}
C. Watering an Array
题目大意:
给你a和b两个数组和一个操作天数d,你有两个操作:1.在数组b的前b[i]个元素,每个加1。2.计算a数组中a[i]==i的个数,并加到你的分数上,然后将a数组全部置为零。每天只能进行一个操作,另外数组b是呈环状的,天数如果大于b的长度,从b的第一个元素重新开始。
题解:
可以先在输入的时候计算初始状态下a[i]==i的个数ans,并且设置一个循环遍历每次进行操作的分数,因为每次操作可以选择加数或者加分置零两种,所以循环次数应为min(2*n+1,d),另外每次循环遍历a数组前b[i]个数,分加数前和后两次判断,加数前a[i]==i的话,分数-1,加分后a[i]==i的话,分数+1。然后每次用sum=max(sum,ans+(d-i)/2)遍历最大得分。提要:因为一般情况下,是直接在第一次操作直接加分置零,然后每两次操作加1分,所以是ans+(d-1)/2,但是如果第一天不加分置零的话,分数就是ans+(d-i)/2;
AC代码:
#include<bits/stdc++.h
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr);
#define endl '\n'
int a[200100],b[200100];
void Solved() {
int n,k,d,ans=0,sum=0;
cin>>n>>k>>d;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]==i)
sum++;
}
for(int i=1;i<=k;i++){
cin>>b[i];
}
b[0]=b[k];
for(int i=1;i<=min(2*n+1,d);i++){
ans=max(ans,(d-i)/2+sum);
int x=b[i%k];
for(int j=1;j<=x;j++){
if(a[j]==j){
sum--;
}
a[j]++;
if(a[j]==j){
sum++;
}
}
}
cout<<ans<<endl;
return ;
}
signed main(void) {
IOS
int ALL = 1;
cin >> ALL;
while(ALL -- ) Solved();
return 0;
}
总结:
还是需要锻炼思维,就类似于C的状态转换,想出来直接就秒了