HDU 5203 Rikka with wood sticks

题目大意:有一根长度为
  
   n
  的木棍,这个木棍是由
  
   n
  个长度为
  
   1
  的小木棍拼接而成,当然由于时间放置的久了,一些小木棍已经不牢固了,所以勇太想让六花把这个木
棍分成正整数长度的
  
   4
  段,其中有
  
   3
  段要没有不牢固的小木棍,勇太希望这
  
   3
  段木棍的长度和可以最大。同时六花希望在满足勇太要求的情况下让这三根木棍能拼成一
个三角形,请问萌萌哒六花有多少种可行的分割方案呢?

解题思路:

先求出所有不牢固小木棍中最左边的位置 L 和最右边的位置 R ,可以确定的是其中一段一定是 [L,R] 。
接着分两种情况考虑:
1. L=1  R=n 
这样剩下的三段是由一整段木棒截来,我们可以枚举最左边一段的长度,这样可以得到一个关于第二段木棍的不等式,稍微讨论一下即可。
2.除了 1 以外的情况
这种情况相对容易,枚举是左边一段还是右边一段作为完整的一段,然后再枚举另外一段的切割点,判断是否合法,如果合法就使答案加一。
时间复杂度 O(n+m) 。
Hack点:1.没开long long。2.没有考虑到第一种情况或者第一种情况写错。3.直接尝试用 O(n2) 的暴力

#include <iostream>
using namespace std;

int main() {
	int n, m, temp;
	while (scanf("%d%d", &n, &m) != EOF) {
		int left = 0x3f3f3f3f, right = 0;
		for (int i = 0; i < m; i++) {
			scanf("%d", &temp);
			left = min(left, temp);
			right = max(right, temp);
		}
		int len_L = left - 1;
		int len_R = n - right;

		if (len_L == 0 && len_R == 0) {
			printf("0\n");

		} else if (len_L != 0 && len_R != 0) {
			long long cnt = 0, ans = 0;
			int len_max = max(len_L, len_R);
			int len_min = min(len_L, len_R);
			for (int i = 1; i <= len_max / 2; i++)
				if (len_L + len_R > 2 * max(len_min, max(i, len_max - i))) {
					if (i == len_max - i)
						ans--;
					cnt++;
				}
			cout << ans + cnt * 2 << endl;

		} else if ((len_L == 0 && len_R != 0) || (len_L != 0 && len_R == 0)) {
			long long cnt = 0;
			int len = len_L + len_R;
			for (int i = 1; i <= (len-1) / 2; i++) {
				len_L = len - i - (len-1) / 2;
				cnt += (len - 1) / 2 - len_L + 1;
			}
			cout << cnt << endl;
		}
	}
	return 0;
}


你可能感兴趣的:(HDU 5203 Rikka with wood sticks)