Codeforces Round #171 (Div. 2)总结

17 篇文章 0 订阅

A题:

      题目是说按所给的漩涡形扩展下去,然后给你一个坐标,问到达该坐标需要转向几次。我的做法是将左边分为4个区域,然后分别对每个区域的2个边进行讨论求解就行了。

对(1,0)点进行了特殊处理。

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
int x,y;
int main()
{
    while(scanf("%d%d",&x,&y)!=EOF)
    {
	int ans=0;
	if(x==1&&y==0)
	    ans=0;
	else if(x>0&&y>=0)
	{
	    if(x>=y)
		ans=(x-1)*4+1;
	    else
		ans=(y-1)*4+2;
	}
	else if(x<=0&&y>0)
	{
	    if(-x<=y)
		ans=(y-1)*4+2;
	    else
		ans=(-x-1)*4+3;
	}
	else if(x<0&&y<=0)
	{
	    if(y>=x)
		ans=(-x-1)*4+3;
	    else
		ans=-y*4;
	}
	else
	{
	    if(x<=-y+1)
		ans=-y*4;
	    else
		ans=(x-1)*4+1;
	}
	printf("%d\n",ans);
    }
    return 0;
}


B题:

      大意是说有n本书,对书进行编号,每本书要消耗ai的时间去阅读,你只能选择对书进行连续的阅读,要求求出在t的时间内最多能阅读多少本书。

      维护一个队列,保证当前书区间的总时间小于等于m,然后更新区间,更新答案即可。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#define MAX 100001
using namespace std;
int book[MAX],sum[MAX];
int n,m;
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
	memset(sum,0,sizeof(sum));
	for(int i=1;i<=n;i++)
	{
	    scanf("%d",&book[i]);
	    sum[i]=sum[i-1]+book[i];
	}
	int pre=0,last=1;
	int ans=0;
	while(last<=n)
	{
	    if(sum[last]-sum[pre]<=m)
	    {
		ans=max(ans,last-pre);
		last++;
	    }
	    else
		pre++;
	}
	printf("%d\n",ans);
    }
    return 0;
}

C题:

其实题意不算太难,就是判断它所查询的区间是否满足题目的要求,要求就是求一个区间内是否满足单增再单减,或者只有单增单减,或者全部相等。

我采用的方法是求出当前点所能到达的最远的单增单减点,最开始是求的前方所能到达的最前端点。

后来我采用当前结点记录所能到达的最远的递增递减点,然后进行判断,然后就能AC了~

代码(前方):

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAX 100001
using namespace std;
int n,m,a[MAX],up[MAX],down[MAX];
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
	for(int i=1;i<=n;i++)
	    scanf("%d",&a[i]);
	up[1]=down[1]=1;
	for(int i=2;i<=n;i++)
	{
	    if(a[i]==a[i-1])
	    {
		up[i]=up[i-1];
		down[i]=down[i-1];
	    }
	    else if(a[i]>a[i-1])
	    {
		up[i]=up[i-1];
		down[i]=i;
	    }
	    else
	    {
		down[i]=down[i-1];
		up[i]=i;
	    }
	}
	for(int i=0;i<m;i++)
	{
	    int ita,itb;
	    scanf("%d%d",&ita,&itb);
	    int mid=down[itb];
	    if(mid<=ita||up[mid]<=ita)
		printf("Yes\n");
	    else
		printf("No\n");
	}
    }
    return 0;
}


代码(后方):

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAX 100001
using namespace std;
int n,m,a[MAX],up[MAX],down[MAX];
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
	for(int i=1;i<=n;i++)
	    scanf("%d",&a[i]);
	up[n]=down[n]=n;
	for(int i=n-1;i>=1;i--)
	{
	    if(a[i]==a[i+1])
	    {
		down[i]=down[i+1];
		up[i]=up[i+1];
	    }
	    else if(a[i]>a[i+1])
	    {
		down[i]=down[i+1];
		up[i]=i;
	    }
	    else
	    {
		up[i]=up[i+1];
		down[i]=i;
	    }
	}
	for(int i=0;i<m;i++)
	{
	    int l,r;
	    scanf("%d%d",&l,&r);
	    int mid=up[l];
	    if(down[mid]>=r)
		printf("Yes\n");
	    else
		printf("No\n");
	}
    }
    return 0;
}

E题:

参照网上别人做的思路,自己做了下。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAX 1000001
using namespace std;
char str[MAX];
int main()
{
    while(scanf("%s",str)!=EOF)
    {
	int ans=0,zero=2,pos=0;
	for(int i=0;i<strlen(str);)
	{
	    if(str[i]=='1')
	    {
		int cou=0;
		while(str[i+cou]=='1')
		    cou++;
		if(cou==1)
		{
		    ans++;
		    if(zero>1)
			pos=1;
		}
		else if(zero==1)
		{
		    ans++;
		    if(pos)
			ans++;
		    pos=0;
		}
		else
		{
		    ans+=2;
		    pos=0;
		}
		i+=cou;
	    }
	    else
	    {
		zero=0;
		while(str[i+zero]=='0')
		    zero++;
		i+=zero;
	    }
	}
	printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值