题意:给出三个数,可以对每个数进行+1,-1,和不改动三种处理;需要求出处理后的三个数两两差值(取绝对值)之和的最小值。
我太菜了,比不上那些大佬三分钟AC,我竟然花了二十多分钟打了个特别low的模拟代码,索性没出bug能一发A了,不然绝对的嘤嘤嘤~
代码实现:
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int q;cin>>q;
while(q--)
{
long long a,b,c;
cin>>a>>b>>c;
if(a>b){int t=a;a=b;b=t;}
if(a>c){int t=a;a=c;c=t;}
if(b>c){int t=b;b=c;c=t;}
if(a==b){
if(c==b+1||b==0){
cout<<0<<endl;
continue;
}
if(c>b+1){
cout<<2*(c-b-2)<<endl;
continue;
}
}
if(b==c){
if(a==b-1||a==b){
cout<<0<<endl;
continue;
}
if(a<b-1){
cout<<2*(b-a-2)<<endl;
continue;
}
}
if(a+1==b){
if(b+1==c){
cout<<0<<endl;
continue;
}
if(b+1<c){
cout<<2*(c-1-b)<<endl;
continue;
}
}
if(b+1==c){
if(a+1==b){
cout<<0<<endl;
continue;
}
if(a+1<b){
cout<<2*(b-1-a)<<endl;
continue;
}
}
if(a+1<b&&b+1<c){
cout<<2*c-2*a-4<<endl;
continue;
}
}
return 0;
}
题意:四个字符表示四种移动方向,需要从(0,0)点出发又回到原点,出原点外的其他点不能重复走,让找出能走的最长路径序列。(细节部分还说出了好几次bug,哎~)
思路:
- 先遍历统计四个方向的个数,如果有一个方向为0,那么意味着移动路线只能是一维的,又因为不能重复走某个点,就只能走两步篮球(例如只有U的个数为0,那么只能LR或RL了)
- 当然如果出现两个不相对的方向同时为0,则不能移动(如R和U都为0,则输出0);如果都不为0,输出路线形成一个矩形就行(两邻边分别为UD的最小值和RL的最小值)。
代码实现:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
char s[MAXN];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int q;cin>>q;
while(q--)
{
cin>>s;
int nl=0,nr=0,nu=0,nd=0;
int n=strlen(s);
for(int i=0;i<n;i++){
if(s[i]=='L')
nl++;
else if(s[i]=='R')
nr++;
else if(s[i]=='U')
nu++;
else nd++;
}
int anl=min(nl,nr);
int anu=min(nu,nd);
if(!anl&&anu){
cout<<2<<endl<<"UD"<<endl;
continue;
}
if(!anu&&anl){
cout<<2<<endl<<"LR"<<endl;
continue;
}
else if(!anl&&!anu)
cout<<0<<endl;
else{
cout<<2*(anl+anu)<<endl;
for(int i=0;i<anl;i++)
cout<<'L';
for(int i=0;i<anu;i++)
cout<<'U';
for(int i=0;i<anl;i++)
cout<<'R';
for(int i=0;i<anu;i++)
cout<<'D';
cout<<endl;
}
}
return 0;
}
C. Yet Another Broken Keyboard
题意:找出包含c1……ck字符的所有子字符串,可以有重复(但却不是同一个,例如aa的子字符串就有a,a,aa三个)。
思路:找出每一个字串的最长值,答案即是这些最长值分别加到1的和(例如第一个例子就有"aba","aba"两个最大长度为3的子串,答案就是(3+2+1)+(3+2+1))。
但是菜到想哭的是我在最后几分钟提交却WA在了第12组数据,呜呜,看了大佬zyh代码后才知道自己其实就只错在数据范围上,没考虑到答案可能会超过int范围,呜呜~~
赛后AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2*1e5+5;
char s[MAXN];
int vis[30];
long long m[MAXN];//答案可能会很大
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,k;
cin>>n>>k;
cin>>s;
//getchar();
for(int i=1;i<=k;i++){
char x;
cin>>x;
//getchar();//个人很好奇明明题意说过有空格,为什么就没有这个getchar()来吃空格和换行
vis[x-'a']=1;
}
int tmp=0,cnt=0;
long long ans=0;//用int就会WA在第12组
for(int i=0;i<n;i++){
if(vis[s[i]-'a'])
tmp++;
else{
m[cnt++]=tmp;
tmp=0;
}
if(i==n-1&&vis[s[n-1]-'a']){
m[cnt++]=tmp;
}
}
for(int i=0;i<cnt;i++){
if(m[i]%2==0)
ans+=(m[i]+1)*(m[i]/2);
else
ans+=(m[i]+1)*(m[i]/2)+(m[i]+1)/2;
}
cout<<ans<<endl;
return 0;
}
当然看了大佬zyh代码后又开始自闭,自己还是走了弯路。。。。
大佬AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2*1e5+5;
char s[MAXN];
int m[MAXN];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,k;cin>>n>>k;
cin>>s+1;
for(int i=1;i<=k;i++){
char x;
cin>>x;
for(int j=1;j<=n;j++)
if(s[j]==x)
m[j]=1;
}
long long ans=0;
for(int i=1;i<=n;i++){
if(m[i])
m[i]=m[i-1]+1;
ans+=m[i];
}
cout<<ans<<endl;
return 0;
}
没错!它就是这么简单明了!哎,还是我太菜了~~