【Best Coder 】 32 B Negative and Positive (NP)

17 篇文章 0 订阅
9 篇文章 0 订阅

思路:题目是根据所给的规则,判断是否在一个区间i-j的结果等于k。

其实要求i-j区间的值我们可以采用1-j的值减去1-i的值即可得到i-j的值。

sum[j]-sum[i]=k

sum[j]-k=sum[i]

问题就可以转化成判断sum[i]是否存在,而sum[i]假如存在的话,一定在求解sum[j]之前求解过了

所以我们不妨将求解过的sum[l]全部假如hash表当中,只要对sum[i]进行判断是否存在即可,不仅方便而且很快。

但是由于题目所给的限制条件。

当i为偶数的时候,相减得到的值就是正确的。所以直接查找sum[j]-k,当然这个时候需要查找的是i为奇数,所以我们还要加入一个变量,确保我们找到的值是一个偶数的前缀和。

但若i为奇数的时候,得到的值则是相反数。

即-(sum[j]-sum[i])=k,转化一下sum[i]=k+sum[j],所以这个时候我们求解的就是sum[j]+k,同样的道理,加入一个变量确保我们求解的时候是一个奇数的前缀和。

详细请看代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#define MAX 4000040
#define mod 1000007
struct pos
{
	long long x;
	int next;
	int po;
}s[MAX];

int head[mod];
int cnt = 0;
void add(long long x,int pos)
{
	int h = (x + mod) % mod;
	for (int i = head[h]; i != -1;i=s[i].next)
	if (s[i].x == x&&pos==s[i].po)return;
	s[cnt].po = pos & 1;
	s[cnt].x = x;
	s[cnt].next = head[h];
	head[h] = cnt++;
}

bool ok(long long x,int pos)
{
	int h = (x + mod) % mod;
	for (int i = head[h]; i != -1; i = s[i].next)
	if (s[i].x == x&&pos==s[i].po)return true;
	return false;
}
int main()
{
	int t;
	cin >> t;
	int icase = 1;
	while (t--)
	{
		memset(head, -1, sizeof(head));
		int n;
		long long k;
		scanf("%d%lld", &n, &k);
		int x;
		long long sum = 0;
		bool flag = 0;
		add(0, 0);//我们要的是正好是一个前缀的时候,
		for (int i = 1; i <=n; i++)
		{
			scanf("%d", &x);
			if (i & 1)
				sum += x;//之前给写反了,就超时了
			else
				sum -= x;
			if (!flag)
			{
				if (ok(sum - k,0))flag = true;
				if (ok(sum + k, 1))flag = true;
				add(sum, i);
			}
		}
		printf("Case #%d: %s\n",icase++, flag ? "Yes." : "No.");
	}
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值