Codeforce Round #336--B. Hamming Distance Sum

题目链接:Hamming Distance Sum

题意:

给两个字符串a,b每个字符串只包含字符1和0。求字符串b的每一个长度和a相同的连续子串与a的汉明距离和。

  • The Hamming distance between two strings s and t of equal length is defined as.
  • find the sum of the Hamming distances between a and all contiguous substrings of b of length|a|.

分析:

两层嵌套循环果然TLE了!又没自己做出来,╮(╯▽╰)╭!看了网上的解题报告。

可以这样想,对于这题而言,每个b的连续子串和a的汉明距离即是不相同的字符个数

再来看看a的移动比较。

a[0]是和b[0],b[1],...,b[lenb-lena]比较,所以单对a[0]的汉明距离是b[0]到b[lenb-lena]中字符不是a[0]的个数。

a[1]是和b[1],b[1],...,b[lenb-lena+1]比较,所以单对a[1]的汉明距离是b[1]到b[lenb-lena+1]中字符不是a[1]的个数。

....所以可以开一个数组cnt[maxn][2],其中cnt[i][0]:到位置i(包括位置i)字符串b中字符0的个数cnt[i][1]:到位置i(包括位置i)字符串b中字符1的个数;位置即代表下标,都是从0开始的。

注意:

  • 在计算单对a[i]的汉明距离是ans要加上对b[i]字符的判断,因为cnt数组是包含位置i的


CODE:

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 200010;
char s1[maxn], s2[maxn];
int len1, len2, cnt[maxn][2];

int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif 
	while (~scanf("%s%s", s1, s2))
	{
		len1 = strlen(s1);
		len2 = strlen(s2);
		memset(cnt, 0, sizeof(cnt));
		cnt[0][s2[0] - '0']++;
		for (int i = 1; i <len2; i++)
		{
			cnt[i][0] = cnt[i - 1][0] + (s2[i] == '0' ? 1 : 0);
			cnt[i][1] = cnt[i - 1][1] + (s2[i] == '1' ? 1 : 0);
		}//cnt[i][0]:在第i个位置之前(包括i)含有字符0的个数,位置从0开始;cnt[i][1]类似
		long long  ans = 0;
		for (int i = 0; i < len1; i++)
		{
			if (s1[i] == '0') ans += cnt[len2 - len1 + i][1] - cnt[i][1] + (s2[i] == '1' ? 1 : 0);
			else ans += cnt[len2 - len1 + i][0] - cnt[i][0] + (s2[i] == '0' ? 1 : 0);
		}
		printf("%I64d\n", ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值