又是一次智障的跌在C题,不多记了,看代码。。。
A题:
题意:
虫子每次都可以跳到他所在位置前面的第一个A,E,I,O,U,Y的出现位置,并且最后可以跳到最后。
思路:
暴力扫一遍位置就行了,注意下尾部字符串末尾终止处理,比赛时候智障了。
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
char s[100005];
int a[10005];
int main()
{
scanf("%s",&s);
int ans=0;
int tep=0;
int len=0;
a[1]=0;
for(int i=0;i<strlen(s);i++)
{
if(s[i]=='A'||s[i]=='E'||s[i]=='O'||s[i]=='I'||s[i]=='U'||s[i]=='Y')
{
a[++len]=i+1;
}
}
a[++len]=1+strlen(s);
for(int i=1;i<=len;i++)
{
//cout<<a[i]<<" ";
ans=max(a[i]-a[i-1],ans);
}
cout<<ans<<endl;
return 0;
}
B题:
题意:士兵走步,第一个数据N,下面有N对,
第一个数据表示第一次迈左腿的人数, 第二个数据表示第一次迈右腿的人数。
询问,你只能交换一次,也可以不交换,使得所有的第一次迈左腿的,与右腿的人数差值的绝对值最大
思路:
先记录左腿,右腿依次的和,然后暴力交换每一行。
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
char s[100005];
int a[10005];
int l[1000005];
int r[1000005];
int lx[1000005];
int rx[1000005];
int main()
{
int k;
cin>>k;
int suml=0,sumr=0;
for(int i=1;i<=k;i++)
{
cin>>l[i]>>r[i];
suml+=l[i];
sumr+=r[i];
}
int maxx=sumr-suml;
if(maxx<0)
maxx=-maxx;
int ans=0;
for(int i=1;i<=k;i++)
{
int tel=suml-l[i]+r[i];
int ter=sumr-r[i]+l[i];
int maxt=tel-ter;
if(maxt<0)
maxt=-maxt;
if(maxt>maxx)
{
maxx=maxt;
ans=i;
}
}
cout<<ans<<endl;
return 0;
}
C题:
这题编了一个半小时不出,最后24秒发现扫一下就可以了,第二天15分钟就AC了。真是个智障
题意:
第一行N,表示第二行有n个数字
第二行有N个数字
第三行K,表示第四行有K个数字
第四行 K个数字。
题目背景是: 第二行都是怪物,数字大的吃数字小的,并且只能吃掉相邻的,吃掉后变为两个数字的和,询问能否通过怪物互相吃掉对方,变成第四行的数字。
思路:注意点四行的K个数字,如果我们拿到第一个数字的话,那一定这个数字是通过第二行前X个构造的,第二个数字,必定是通过第二行前X+1->Y个数字构造的,那么我们只需要如此做就AC嘞!(注意,因为怪物不能直接互换位置,所以只需要扫一下和就行了)
1: 扫一下第二行,记录数字的和,如果数字的和==第四行的第i个数字,就把当前记录清空,继续找i+1个,否则找不到就跳出去。(具体见程序solve函数有注释)
2: 如果可以将这些数字经过若干步,变成第四行要求的数字,那么我们只需要再重新调用下之前的函数,把操作打印出来即可。
3: (掉坑里的一步): 什么也别想,直接暴力扫一下,数据很小,我们只需要记录下当前的最大值的位置,然后进行左或者右的判断,以及开始位置。
如果没看懂,看代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
int a[10005];
int need[10005];
int pos[10005];
int vis[10005];
int all;
int solve(int x,int op )
{
memset(vis,0,sizeof(vis));
int maxx=0;
int cnt=0;
//记录最大值所在的位置。如果都是最大值那就不成立,第一次调用solve函数时候的判断
for(int i=pos[x-1]+1;i<=pos[x];i++)
{
if(a[i]>maxx)
{
cnt=0;
vis[++cnt]=i;
maxx=a[i];
}
else if(a[i]==maxx)
{
vis[++cnt]=i;
}
}
int t=0;
for(int i=pos[x-1]+1;i<=pos[x];i++)
{
if(a[i]==maxx)
t++;
}
if(t!=1&&t==pos[x]-pos[x-1])
return 0;
//第二次调用solve 函数时候的输出:
if(op==1)
{
int bt;
int l=1,r=1;
//判断哪个最大位置可以走,如果最大位置吃掉了任意一个数字,比如 3 3 1 第二个三吃掉1 就变成了最大的最大,因为即便之前有和他相同的,但是他+1必定比之前的大
for(int i=1;i<=cnt;i++)
{
//扫面左边和右边
l=1,r=1;
if(vis[i]==pos[x-1]+1||(vis[i]!=pos[x-1]+1&&vis[i]==vis[i-1]+1) )
l=0;
if(vis[i]==pos[x]||vis[i]==vis[i+1]-1 )
r=0;
if(l==1||r==1)
{
bt=vis[i];
break;
}
}
//下面的步骤不要忘记脚标的改变,
if(l==1)
{
//如果可以往左吃,先吃到最左再吃到最右,注意输出的位置
for(int i=bt;i>pos[x-1]+1;i--)
{
printf("%d ",i-all);//当前位置
printf("L\n");
}
for(int i=bt;i<pos[x];i++)
{
printf("%d ",pos[x-1]+1-all);//一直是最左
printf("R\n");
}
}
else if(r==1)//和最左相同,各位自己寻思下。
{
for(int i=bt;i<pos[x];i++)
{
printf("%d ",bt-all);
printf("R\n");
}
for(int i=bt;i>pos[x-1]+1;i--)
{
printf("%d ",i-all);
printf("L\n");
}
}
}
return 1;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int k;
cin>>k;
for(int i=1;i<=k;i++)
{
scanf("%d",&need[i]);
}
int sum=0;
int cnt=1;
int over=0;
int i;
//下面的一步,如果不能组合成要求的数字就结束。
for( i=1;i<=n;i++)
{
sum+=a[i];
if(sum==need[cnt])
{
pos[cnt]=i;
sum=0;
cnt++;
}
else if(sum>need[cnt])
{
over=1;
break;
}
}
pos[0]=0;
if(i!=n+1||cnt!=k+1)
over=1;
if(over)
printf("NO\n");
if(over==0)
{
//下面的一步,如果可以组合成,但是不满足可以互相吃掉的要求 就比如 2 2 2 可以构成6 但是实际上不可以互相吃掉就跳出
//详情见solve函数
for( i=1;i<=k;i++)
{
if(solve(i,0)==0)
{
over=1;
break;
}
}
if(over)
{
printf("NO\n");
}
else
{
printf("YES\n");
all=0;
//都已经判断OK了。输出
//注意all数字是改脚标值的。
for( i=1;i<=k;i++)
{
solve(i,1);
all+=pos[i]-pos[i-1]-1;
}
}
}
return 0;
}