2013 ACM/ICPC 长沙网络赛 J Candies (ZOJ)

开始看到这道题了, 不过没有很仔细的思考就去看前面的题目去了。。 还有不到1H 的时候想起了做法, 之后敲, 不过敲完之后又BUG, DEBUG 也没有完成 比赛就结束了。

n%3!=2 的情况下 , 能确定 所有每个人的值。

n%3==2 && 存在 给定的数a[i]!=-1且 i%3!=0 , 这种情况下 也能确定 每个值。

其他情况下 , 可能序列不唯一, 形成了 OOXOOXOOXOOX.........OOX  的形式 O未知,X已知。 假设 num[1]=b[1](第一个数的值=前两个数的和)num[2]=0; 之后每个数都能确定,在i%3==2的位置有可能出现负数, 用min1记录。 当询问  i%3==1的 值时 ,输出 num[i]+min1;

同理 再次使num[1]=0 , num[2]=b[1];   min2记录 i%3==1位置的 最小值  询问 i%3==2 的值时, 输出 num[i]+min2 ;

询问 i%3==0的时候 , 直接输出num[i];

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define INF 1000000000
#define N 100005
int n,a[N],b[N],num[N],te1[N],te2[N],m;
int flag1,flag2;
int main()
{
    //freopen("in.txt","r",stdin);
    int i,j,k;
    while(scanf("%d",&n)!=EOF)
    {
        flag1=flag2=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==-1) flag1=1;
            if(!flag2 && a[i]!=-1 && i%3!=0) flag2=i;
        }
        for(i=1;i<=n;i++)
        {
            scanf("%d",&b[i]);
        }
        memset(num,-1,sizeof(num)); // memset - num
        if(!flag1)
        {
            int tmp;
            scanf("%d",&m);
            while(m--)
            {
                scanf("%d",&tmp);
                tmp++;
                printf("%d\n",a[tmp]);
            }
        }
        else //not all is known
        {
            num[3]=b[2]-b[1];
            for(i=2;i*3<=n;i++)
            {
                int tt=i*3;
                num[tt]=b[tt-1]-b[tt-2]+num[tt-3];
            }
            if(n%3!=2)// all is certain
            {
                num[n-2]=b[n-1]-b[n];
                for(i=1;n-2-3*i>=1;i++)
                {
                    int tt=n-2-3*i;
                    num[tt]=b[tt+1]-b[tt+2]+num[tt+3];
                }
                for(i=1;i<=n;i++)
			 {
			 	if(num[i]==-1)
				{
					if(i==1) num[i]=b[1]-num[2];
					else if(i==n) num[n]=b[n]-num[n-1];
					else num[i]=b[i]-num[i-1]-num[i+1];
				}
			 }
			 scanf("%d",&m);
			 while(m--)
			 {
			 	int tmp;
			 	scanf("%d",&tmp);
			 	tmp++;
			 	printf("%d\n",num[tmp]);
			 }
            }
            else
		  {
		  	if(flag2)// this  is certain
			{
				int g=flag2;
				num[g]=a[g];
				if(g==1) num[2]=b[2]-num[1]-num[3];
				if(g==n) num[n-1]=b[n-1]-num[n]-num[n-2];
				for(i=g-1;i>=1;i--)
				{
					if(num[i]==-1)
					{
						num[i]=b[i+1]-num[i+1]-num[i+2];
					}
				}
				for(i=g+1;i<=n;i++)
				{
					if(num[i]==-1)
					{
						num[i]=b[i-1]-num[i-1]-num[i-2];
					}
				}
				scanf("%d",&m);
				int tmp;
				while(m--)
				{
					scanf("%d",&tmp);
					tmp++;
					printf("%d\n",num[tmp]);
				}
			}
			else // only this is uncertain
			{
				for(i=1;i<=n;i++)
				{
					te1[i]=te2[i]=num[i];
				}
				int min1,min2;
				te1[1]=b[1]; te1[2]=0;
				te2[1]=0; te2[2]=b[1];
				min1=min2=0;
				for(i=4;i<=n;i++)
				{
					if(i%3==0) continue;
					te1[i]=b[i-1]-te1[i-2]-te1[i-1];
					min1=min(min1,te1[i]);
					te2[i]=b[i-1]-te2[i-1]-te2[i-2];
					min2=min(min2,te2[i]);
				}
				int tmp;
				scanf("%d",&m);
				while(m--)
				{
					scanf("%d",&tmp);
					tmp++;
					if(tmp%3==1) printf("%d\n",te1[tmp]+min1);
					else if(tmp%3==2) printf("%d\n",te2[tmp]+min2);
					else printf("%d\n",num[tmp]);
				}
			}
		  }
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值