http://codeforces.com/contest/733
A. Grasshopper And the String
其实就是统计最长连续的非元音字符长度,+1输出
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100005;
typedef long long int ll;
char s[120];
int main()
{
scanf("%s",s);
int len = strlen(s);
int ans = 0,con=0;
for(int i=0;i<len;++i)
{
if(s[i]!='A' && s[i]!='E' && s[i]!='I' && s[i]!='O' && s[i]!='U' && s[i]!='Y')
con++;
else {
ans = max(ans,con);
con=0;
}
}
ans = max(ans,con);
printf("%d\n",ans+1);
return 0;
}
B. Parade
思路很简单,检查左右大小的一致性,左恒大于等于右,或者右恒大于等于左,就输出0,否则就输出相减绝对值最大的列数,左大于右输正最大,右大于左输负数里面绝对值最大的,注意输出的是列数
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 100005;
typedef long long int ll;
int a[maxn][3];
int main()
{
int n;
scanf("%d",&n);
ll lef = 0,rig = 0,f=1,r=1;
for(int i=0;i<n;++i)
{
scanf("%d %d",&a[i][0],&a[i][1]);
a[i][2]=a[i][1] - a[i][0];
if(a[i][2]<0)f=0;//全部右边大于左边
if(a[i][2]>0)r=0;
lef+=a[i][0];
rig+=a[i][1];
}
if(f || r){
printf("0\n");
return 0;
}
ll ma = abs(lef-rig);
int ans = 0;
if(lef != rig){
int mt = 0,p=0,q=0,mi=0;
for(int i=0;i<n;++i)
{
if(a[i][2]>mt){//正数最大
mt=a[i][2];
p=i;
}
if(a[i][2]<mi){//负数最小
mi=a[i][2];
q=i;
}
}
ll tlef = lef-a[p][0]+a[p][1],trig =rig-a[p][1]+a[p][0];
ll tma = abs(tlef-trig);
if(tma>ma){
ans=p;
ma=tma;
}
tlef = lef-a[q][0]+a[q][1];trig =rig-a[q][1]+a[q][0];
tma = abs(tlef-trig);
if(tma>ma){
ans=q;
ma=tma;
}
printf("%d\n",ans+1);
}else {
int mt = abs(a[0][2]),p=0;
for(int i=0;i<n;++i)
{
if(abs(a[i][2])>mt){
mt=abs(a[i][2]);
p=i;
}
}
printf("%d\n",p+1);
}
return 0;
}
C. Epidemic in Monstropolis
打的时候没做出来,估计是没考虑 3 3 1 或 1 3 3这种情况了,还奇思妙想的想过是否全部区间和都满足的情况下还多出几只怪兽,然后等这几只怪兽看完病就会符合了,后来看数据发现并没有这种可能。
思路:首先检查某一连续区间的和是否等于b[i],看是否全部满足,
满足之后检查每一段区间的值是否一致,一致的话吃不动,不一致的话找最大值,遇到多个最大值的情况需要判断从哪只开始吃,所以位置的判断很重要,自己画图推导一下就可以了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long int ll;
const int maxn = 505;
int a[maxn],b[maxn],n,k,tot,num[maxn];
int suma[maxn],sumb[maxn];
char dire[maxn];
bool solve(int l,int r,int k)
{
if(l==r)return 1;
int maxv=0,pos=-1;
for(int i=l;i<=r;++i)maxv=max(maxv,a[i]);
for(int i=l;i<=r;++i){
if(a[i]== maxv && ((i!=l && a[i]>a[i-1])||(i!=r && a[i]>a[i+1]))){//133 331,找开始吃的位置
pos=i;
break;
}
}
if(pos==-1)return 0;
if(pos!=l && a[pos]>a[pos-1])//默认先吃左边 ,不是真的吃,pos不移动
{
for(int i=pos;i>l;--i)
{
num[++tot]=i-l+k;// pos-L是距离,+1是以L开始算pos的下标,前有k-1个数,(pos-L + 1) + k-1;
dire[tot]='L';
}
for(int i=pos;i<r;++i)
{
num[++tot]=k; //吃完了左边,下标就一直是k
dire[tot]='R';
}
}else {//否则先吃右边
for(int i=pos;i<r;++i)
{
num[++tot]=pos-l+k;//向右吃位置一直是pos,pos-L是距离,+1是以L开始算pos的下标,前有k-1个数,所以是(pos - L + 1) +k-1
dire[tot]='R';
}
for(int i=pos;i>l;--i)
{
num[++tot]=i-l+k;// 吃完右边了,(pos - L +1) + k-1;
dire[tot]='L';
}
}
return 1;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i){scanf("%d",&a[i]);suma[i]=suma[i-1]+a[i];}
scanf("%d",&k);
for(int i=1;i<=k;++i){scanf("%d",&b[i]);sumb[i]=sumb[i-1]+b[i];}
if(suma[n]!=sumb[k]){
printf("NO\n");return 0;
}
int pre = 0;
for(int i=1;i<=k;++i){
int found = 0;
for(int j=1;j<=n;++j){
if(suma[j]==sumb[i]){
found = 1;
//a[pre+1] ~ a[j]区间是否存在一种情况使得最后剩下一只怪兽且体重为 b[i]
if(!solve(pre+1,j,i))
{
printf("NO\n");
return 0;
}
pre=j;
}
}
if(!found){
printf("NO\n");
return 0;
}
}
printf("YES\n");
for(int i=1;i<=n-k;++i)
printf("%d %c\n",num[i],dire[i]);
return 0;
}
D. Kostya the Sculptor
思路很简单,因为限制半径的是最短的边,所以输入的时候a存最长的,c存最短的边就好,因为只能最多选两个长方体,而我们知道两个长方体合起来最多只能改变一个变量,就是改变最短的那条边或者不匹配的那条边,比如12 6 6 ,6 6 6会变成18 6 6,所以存起来排个序,排序后判断相邻的两个长方体是否至少有两条边相同长度,匹配的话就取min(b,c1+c2),因为最短边加起来是有可能大于次长边的,时间复杂度是0(n+nlog n),注意了不匹配的长方体是不能合起来的
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 100050;
typedef long long int ll;
struct node {
ll a,b,c;
int d;
}t[maxn];
bool cmp(struct node a,struct node b)
{
if(a.a>b.a)return 1;
else if(a.a==b.a){
if(a.b>b.b)return 1;
else if(a.b==b.b){
return a.c>=b.c?1:0;
}
return 0;
}
return 0;
}
int main()
{
int n;
scanf("%d",&n);
ll cmax = 0;
int ans=0;
for(int i=1;i<=n;++i){
ll aa,bb,cc;
scanf("%lld %lld %lld",&aa,&bb,&cc);
t[i].a = max(aa,max(bb,cc));
t[i].c = min(aa,min(bb,cc));
t[i].b = aa+bb+cc-t[i].a-t[i].c;
t[i].d=i;
if(t[i].c>cmax){
cmax=t[i].c;
ans=i;
}
}
sort(t+1,t+n+1,cmp);
int pick=1,one=-1,two=-1;
for(int i=1;i<n;++i)
{
if(t[i].a>cmax && t[i].b>cmax){
int j=i+1;
if(t[i].a==t[j].a && t[i].b==t[j].b)
{
ll lest = min(t[i].b,t[i].c+t[j].c);
if(lest>cmax){
pick=2;
cmax = lest;
one = t[i].d;
two = t[j].d;
}
}
}
}
printf("%d\n",pick);
if(pick==1)printf("%d\n",ans);
else printf("%d %d\n",one,two);
return 0;
}