zoukankan      html  css  js  c++  java
  • 挑战程序设计竞赛选录:1

     计算机 1s 的计算能力:1000 000 次, 游刃有余; 10 000 000,勉强; 100 000 000,很悬,一般不能。   

    1.1 抽签

    有 n 张纸片, 每个纸片上一个任意数字 ki 。取出 1 张,记下数字后放回,取 4 次。如果 4 个数字的和是 m, 则赢。给定一个 m, 判断是否有赢的可能性 (输出 Yes or No)。

     Limits : (1 <= n <= 1000, 1 <= m <= 108, 1<= ki <= 108)

    样例1:输入:n = 3, m = 10, k = {1, 3, 5}     输出: Yes (如:1, 1, 3, 5)

    样例2:输入:n = 3, m = 9, k = {1, 3, 5}     输出: No (不存在)

    思路: 若递归四次: 10004 >> 109, 肯定超时,故此方法不可取。

    优化方法:任意两个的和共 n2 个, 只要从 n2 个数中找到有没有两个数的和为 m 即可。同时,对这 n2 个数排序,利用二分查找求解。

    时间复杂度: O(N2logN)

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    int main () {
    	int n, m;
    	cin >> n >> m;
    	vector<int> k(n);
    	vector<int> sum(n*n);
    	for (int i = 0; i < n; ++i) cin >> k[i];
    	/**********************************************************/
    	for (int i = 0; i < n; ++i) {
    		for (int j = 0; j < n; ++j) {
    			sum[i*n+j] = k[i] + k[j];
    		}
    	}
    	sort(sum.begin(), sum.end());
    	bool exist = false;
    	for(int i = 0; i < n; ++i) {
    		if (binary_search(sum.begin(), sum.end(), m-sum[i])) {
    			exist = true;
    			break;
    		}
    	}
    	if(exist) cout << "Yes" << endl;
    	else cout << "No" << endl;
    	return 0;
    }
    

     1.6.1 三角形 

    有 n 根棍子,棍子 i 长度 ai, 选出 3 根组成周长尽可能长的三角形。输出最大周长,若无法组成三角形则输入为 0。

    Limits: (3 <= n <= 100000, 1 <= ai <= 106)

    样例1: 输入: n = 5, a = {2, 3, 4, 5, 10}   输出:12 (3, 4, 5)

    样例2: 输入: n = 4, a = {4, 5, 10, 20}     输出: 0 

    思路: 假设 a <= b <= c。只要满足 a + b > c 即可组成三角形。

    因此,2b > c ,对每个 A[i] (即 b) 只要在有序数组 A 中找出小于 2b 的第一个元素 c , 若其满足 c - b < a (即 A[i-1]), 则组成一个以 A[i] 为中间长度的边的周长最大的三角形, 否则若是 c - b >= a (即 A[i-1]), 则不存在以 A[i] 为中间边的三角形。 时间复杂度 : O(NlogN)

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    int binary_find (vector<int>& A, int L, int H, int value) {
    	if (A[H] < value) return A[H];
    	while (L <= H) {
    		int mid = (L+H) >> 1;
    		if (A[mid] >= value) H = mid-1;
    		else if (A[mid+1] >= value) 
    			return A[mid];
    		else L = mid + 1;
    	}
    	return 0;
    }
    
    int main () {
    	int n;
    	cin >> n;
    	vector<int> a(n);
    	for (int i = 0; i < n; ++i) cin >> a[i];
    	/********************************************************/
    	sort(a.begin(), a.end());
    	int ans = 0;
    	for (int i = n-2; i > 0; --i) {
    		int c = binary_find(a, i+1, n-1, a[i] << 1);
    		if ( c && c < a[i] + a[i-1]) {
    			ans = c + a[i] + a[i-1];
                            break;
    		}
    	}
    	cout << ans << endl;
    	return 0;
    }
    

    1.6.2 Ants (蚂蚁)

    n 只蚂蚁以 1cm/s 的速度在长为 Lcm 的竿子上爬行,爬到端点掉落。竿子很细,导致蚂蚁相遇时只能反向爬回。每只蚂蚁距离竿子左端距离 xi, 但不知其朝向。计算所有蚂蚁落下竿子的最短时间和最长时间。

    Limits: (1 <= L <= 106, 1 <= n <= 106, 0 <= xi <= L)

    样例:输入: L = 10, n = 3, x = {2, 6, 7}    输出: min = 4 (左、 右、 右)

    思路:由于蚂蚁都相同,所以两只蚂蚁相遇后交错而过和反向爬回是一样的。所以,可以看成每只蚂蚁是独立运动的。

    void solve(int x[], int n, int L) {
    	int minT = 0, maxT = 0;
    	for (int i = 0; i < n; ++i) {
    		minT = max(minT, min(x[i], L - x[i]));
    		maxT = max(maxT, max(x[i], L - x[i]));
    	}
    	cout << minT << endl << maxT << endl;
    }
    
  • 相关阅读:
    day22 sys模块(☆☆☆)json & pickle模块(☆☆☆☆)
    day22 OS模块
    day21 time时间模块
    day21 if __name__==""__main__""的用法
    day21 模块
    day20 装饰器 (装饰器=高阶函数+函数嵌套+闭包)加上参数
    day19 生产者模型-next与send用法详解-生产者消费者模型
    day19 生成器函数的好处
    zzq's sort [思维题]
    三元组 [01Trie]
  • 原文地址:https://www.cnblogs.com/liyangguang1988/p/4002197.html
Copyright © 2011-2022 走看看