HDU4908BestCoder Sequence(组合数学)

题目:HDU4908BestCoder Sequence(组合数学)

题目大意:给出一串数字,要求找其中的子串,这个子串重新排序后,中位数是M,ps:M在这个串中只会出现一次。

解题思路:这题之前题意都没有理解清楚,还以为只能从M这个数的位置向左向右扩展的子串中找,但是因为是可以在重新排序的。所以这样的做法就不对了。

对于一个串来说,只要这个串是奇数长度,并且中位数在里面,而且这里面大于和小于中位数的长度相等,那么这个子串就是所求的。例如 ; 1 3 5中位数3.

那么每个数字都有个下标p,并且用两个数组A,B。A记录的是中位数位置之前(包括中位数的位置)的位置出现比M小的个数,B记录的是中位数位置之后的位置出现比M小的个数。

例如:1 2 3 4 5  M = 3

0 1 2   --- A (记录的个数不包括当前位置)

2 2 2 --- B (包括当前位置)

那么Pi - Pj = 2 * (B【i】 - A【j】) 化简:Pi  - 2 * B【i】 = Pj - 2 * A【j】 = K;所以只要找B中等于K的位置,和A中等于K的个数,相乘就是所求的。

代码:

#include <cstdio>
#include <cstring>
#include <map>

using namespace std;

const int N = 4e4 + 5;
typedef long long ll;

map<int , int> A, B;
map<int , int>::iterator it;

int main () {

	int n, m;
	int num;
	while (scanf ("%d%d", &n, &m) != EOF) {

		A.clear();
		B.clear();
		int i;
		int sum = 0;
		bool flag = 0;
		for (i = 0; i < n; i++) {

			scanf ("%d", &num);
			if (num == m) {
				flag = 1;
			}
			A[i - 2 * sum]++;
			if (num < m)
				sum++;
			if (flag)
				break;
		}

		B[i - 2 * sum]++;
		for (int j = i + 1; j < n; j++) {

			scanf ("%d", &num);
			if (num < m)
				sum++;
			B[j - 2 * sum]++;
		}

		if (!flag)
			printf ("0\n");
		else {

			int ans = 0;
			for (it = A.begin(); it != A.end(); it++)
				ans += A[it->first] * B[it->first];
			printf ("%d\n", ans);
		}
	}
	return 0;
}
时间: 2024-09-09 05:12:28

HDU4908BestCoder Sequence(组合数学)的相关文章

hdu(2062)-Subset sequence 组合数学

题意:求集合{1,2,3...n}的第m个排列子集合.集合的大小按字典树排. 例两个元素的排列子集合按字典树排列是:{1},{1,2},{2},{2,1}: 解法:一个一个元素来确定,每次把剩余的元素按大小顺序排列在num中,然后根据排列组合原理直接计算下一个位置的元素的大小,直到排列数为0停止: 代码: /****************************************************** * author:xiefubao **********************

poj 1019 Number Sequence (组合数学)

链接:poj 1019 题意:有一个由数字组成的序列规律为 112123123412345123456123456712345678123456789123456789101234567891011 ... 输入位置n,计算这一串数字第n位是什么数字 分析:模拟分组,把1看做第1组,12看做第2组,123看做第3组... 那么第i组就是存放数字序列为 [1,i]的正整数,但第i组的长度不一定是i, 已知输入查找第n个位的n的范围为(1 ≤ n ≤ 2147483647), 那么至少要有31268

hdu4908 &amp; BestCoder Round #3 BestCoder Sequence(组合数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4908 BestCoder Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 618    Accepted Submission(s): 214 Problem Description Mr Potato is a code

HDU 4908 BestCoder Sequence(组合数学)

HDU 4908 BestCoder Sequence 题目链接 题意:给定一个序列,1-n的数字,选定一个作为中位数m,要求有多少连续子序列满足中位数是m 思路:组合数学,记录下m左边和右边一共有多少种情况大于m的数字和小于n数组的差,然后等于左边乘右边所有的和,然后最后记得加上左右两边差为0的情况. 当时也是比较逗,还用树状数组去搞了,其实完全没必要 代码: #include <cstdio> #include <cstring> #define lowbit(x) (x&am

hdu4675 GCD of Sequence 莫比乌斯+组合数学

/** 题目:hdu4675 GCD of Sequence 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4675 题意:给定n个数的a数组,以及m,k: 构造满足1<=bi<=m,和a数组恰好k个位置ai!=bi的b数组. 输出b数组所有数的gcd分别为1~m的数组个数. 思路: f(n)表示gcd==n的数组个数. g(n)表示gcd是n的倍数的数组个数. f(n) = sigma[n|d]mu[d/n]*g(d); 如何求g(d)呢? 如果没

hdu4908 &amp;amp; BestCoder Round #3 BestCoder Sequence(组合数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4908 BestCoder Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 618    Accepted Submission(s): 214 Problem Description Mr Potato is a code

bzoj 1005: [HNOI2008]明明的烦恼(组合数学 purfer sequence)

1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 3945  Solved: 1563 [Submit][Status][Discuss] Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在 任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 < N < = 1000), 接下来N行,第i+1行给出第i

Codeforces 466D Increase Sequence(dp+组合数学)

题目链接:Codeforces 466D Increase Sequence 题目大意:给定一个序列,现在可以选中一段区间,使得整段区间上每个位置数加1,要求最后每个位置都为h,并且选中的区间不能有相同l或则r. 解题思路:因为每个位置最多有一个起始和一个终止(区间). ai和ai+1差的绝对值超过1,则肯定是不行的, ai+1?ai=1,那么一定要从i+1的位置新起一段区间 ai+1?ai=?1,那么一定要在i+1的位置上终止一段区间,C(1ai) ai+1?ai=0,可以不变,也可以终止并新

poj 1019 Number Sequence 【组合数学+数字x的位宽函数】

题目地址:http://poj.org/problem?id=1019 Number Sequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35680   Accepted: 10287 Description A single positive integer i is given. Write a program to find the digit located in the position i in