【HDU - 5914 】Triangle (打表 或 set维护)

163 篇文章 1 订阅
34 篇文章 0 订阅

题干:

Mr. Frog has n sticks, whose lengths are 1,2, 3⋯⋯n respectively. Wallice is a bad man, so he does not want Mr. Frog to form a triangle with three of the sticks here. He decides to steal some sticks! Output the minimal number of sticks he should steal so that Mr. Frog cannot form a triangle with 
any three of the remaining sticks.

Input

The first line contains only one integer T (T≤20T≤20), which indicates the number of test cases. 

For each test case, there is only one line describing the given integer n (1≤n≤201≤n≤20).

Output

For each test case, output one line “Case #x: y”, where x is the case number (starting from 1), y is the minimal number of sticks Wallice should steal.

Sample Input

3
4
5
6

Sample Output

Case #1: 1
Case #2: 1
Case #3: 2

解题报告:

    看网上的题解都说是打表,那怎么打的表啊?手推?万一不正确呢?有点侥幸啊。。其实这题也可以搜索来找答案,但是还有更好的方法,比如用set,也是0ms过,我看好多打表的都是15ms,不知道是什么情况。

AC代码:

#include<bits/stdc++.h>

using namespace std;

int main()
{
	int t,n;
	int iCase = 0;
	scanf("%d",&t);
	while(t--) {
		scanf("%d",&n);
		printf("Case #%d: ",++iCase);
		if(n <= 3) {
			printf("0\n");continue;
		}
		int ans = 0;
		set<int> st;
		for(int i = 1; i<=n; i++) st.insert(i);
		set<int>::iterator it,itt,ittt,qq;
		
		int flag = 1;
		while(flag) {
			qq=st.end();
			qq--;qq--;
			for(it = st.begin(); it!=qq; ++it) {
				itt=++it;
				--it;
				ittt=++itt;
				--itt;
				if(*it + *itt > *ittt) {
					st.erase(ittt);ans++;break;
				}
				++it;
				if(it == qq) flag=0;
				--it;
			}
			
		}
		printf("%d\n",ans);
	}
	return 0 ;
}

总结:

    刚开始写的时候错误还是比较多的,比如for遍历的时候it != st.end(),但是这题不行,因为itt和ittt就越界了。。所以这题qq迭代器就是记录一下st.end()往前两个是多少。还有一个坑点就是需要实时计算qq的值,因为你有erase操作,所以st.end()就在变,所以qq也要跟着变才对。再就是n<=3的时候要特判,输出格式的空格要注意。


还有一个类似的题目在别的题解上看到了这里粘贴一下:

切金条

一根金条长31厘米,如果把它切成数段,使其中的一段或几段能够接成长为1到31中任何整数的金条,请问要切几次?

题解:第一反应是斐波那契数列1 2 3 5 8 12,切5刀,结果错了,这道题应该用二进制做。123是不需要3的,因为12可以构成3,所以124是更好的选择。

这两道题好像,但是这是两道题,一定要仔细区分开。

1 2 4 8 16,和正好31,切4刀,答案是4。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值