木棒拼图(multiset 的应用)----今日头条2017后端工程师实习生笔试题

[编程题] 木棒拼图

有一个由很多木棒构成的集合,每个木棒有对应的长度,请问能否用集合中的这些木棒以某个顺序首尾相连构成一个面积大于 0 的简单多边形且所有木棒都要用上,简单多边形即不会自交的多边形。

初始集合是空的,有两种操作,要么给集合添加一个长度为 L 的木棒,要么删去集合中已经有的某个木棒。每次操作结束后你都需要告知是否能用集合中的这些木棒构成一个简单多边形。


输入描述:

每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n 表示操作的数量(1 ≤ n ≤ 50000) , 接下来有n行,每行第一个整数为操作类型 i (i ∈ {1,2}),第二个整数为一个长度 L(1 ≤ L ≤ 1,000,000,000)。如果 i=1 代表在集合内插入一个长度为 L 的木棒,如果 i=2 代表删去在集合内的一根长度为 L 的木棒。输入数据保证删除时集合中必定存在长度为 L 的木棒,且任意操作后集合都是非空的。



输出描述:

对于每一次操作结束有一次输出,如果集合内的木棒可以构成简单多边形,输出 "Yes" ,否则输出 "No"。


输入例子:
5
1 1
1 1
1 1
2 1
1 2

输出例子:
No
No
Yes
No
No
判断几条棍子能否组成面积大于 0 的简单多边形只需满足一个条件:

木棍集合中找出一根最长的,记为 max_len
除了这一根外,剩下的长度之和,记为 Len

则必须满足 Len > max_len 。

换言之, 设总长度为 Tlen,
则仅当 Tlen - max_len > max_len 时,才能组成面积大于0 的简单多边形

那剩下的编程就简单多了

#include <set>
#include <iostream>
#include <string>
#include <vector>

using namespace::std ;

int main() {
    int input ;
    
    while ( cin >> input ) {
        vector<string> result ;
        multiset<int> ms ;
        int sum_length = 0 ;
        for ( int i = 0; i < input; ++ i ) {
            int opt, len ;
            cin >> opt >> len ;
            if ( opt == 1 ) {
                sum_length += len ;
                ms.insert( len ) ;
            } else if ( opt == 2 ) {
                multiset<int>::iterator iter = ms.find( len ) ;
                if ( iter != ms.end() ) ms.erase( iter ) ;
                sum_length -= len ;
            }
            
            int max_length = *( ms.rbegin() ) ;
            if ( sum_length - max_length > max_length ) 
                result.push_back( "Yes" ) ;
            else result.push_back( "No" ) ;
        }
        
        for ( int i = 0; i < result.size(); ++ i ) {
            cout << result[i] << endl ;
        }
    }
    
    return 0 ;
}


第二次做:

#include <iostream>
#include <vector>

using namespace::std;

int getmax(vector<int>& vec) {
	int max = 0;
	for (int i = 0; i < vec.size(); ++i) {
		if (max < vec[i]) max = vec[i];
	}
	return max;
}

int getsum(vector<int>& vec) {
	int sum = 0;
	for (int i = 0; i < vec.size(); ++i) {
		sum += vec[i];
	}
	return sum;
}

int main() {
	int n;

	while (cin >> n) {
		vector<pair<int, int>> vec;
		for (int i = 0; i < n; ++i) {
			int op, len;
			cin >> op >> len;
			vec.push_back(make_pair(op, len));
		}

		vector<int> vol;
		for (int i = 0; i < n; ++i) {
			if (vec[i].first == 1) {
				vol.push_back(vec[i].second);
			}
			else if (vec[i].first == 2) {
				vector<int>::iterator iter = vol.begin();
				for (; iter != vol.end(); ++iter) {
					if (*iter == vec[i].second) break;
				}
				if (iter != vol.end()) vol.erase(iter);
			}

			int max = getmax(vol);
			int sum = getsum(vol);
			if (sum - max > max) 
				cout << "Yes" << endl;
			else 
				cout << "No" << endl;
		}
	}

	return 0;
}

#include <iostream>
#include <set>

using namespace::std;

int main() {
	int n;

	while (cin >> n) {
		multiset<int> s;
		int sum = 0;
		for (int i = 0; i < n; ++i) {
			int op, len;
			cin >> op >> len;
			if (op == 1) {
				s.insert(len);
				sum += len;
			}
			else if (op == 2) {
				multiset<int>::iterator iter = s.find(len);
				if (iter != s.end()) {
					s.erase(iter);
					sum -= len;
				}
			}

			int max = *s.rbegin();
			if (sum - max > max)
				cout << "Yes" << endl;
			else
				cout << "No" << endl;
		}
	}

	return 0;
}


list 版

#include <iostream>
#include <vector>
#include <list>

using namespace::std ;

int main() {
    int n ;
    
    while ( cin >> n ) {
        if ( n <= 0 ) continue ;
        
        vector<pair<int, int>> op ;
        for ( int i = 0; i < n; ++ i ) {
            int operation, length ;
            cin >> operation >> length ;
            op.push_back( make_pair( operation, length ) ) ;
        }
        
        int max, sum ;
        list<int> ls ;
        for ( int i = 0; i < op.size(); ++ i ) {
            max = 0 ;
            sum = 0 ;
            
            if ( op[i].first == 1 ) {
                ls.push_back( op[i].second ) ;
            }
            else if ( op[i].first == 2 ) {
                int tmp = op[i].second ;
                list<int>::iterator iter = ls.begin();
                for ( ; iter != ls.end(); ++ iter ) {
                    if ( *iter == tmp ) break ;
                }
                ls.erase( iter ) ;
            }
            
            for ( list<int>::iterator iter = ls.begin(); iter != ls.end(); ++ iter ) {
                if ( max < *iter ) max = *iter ;
                sum += *iter ;
            }
            
            if ( sum - max > max ) cout << "Yes" << endl ;
            else  cout << "No" << endl ;
        }
    }
    
    return 0 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值