多层for循环优化

  • 1.6.1 找出最大周长的三角形
/*可以用穷举找出最长,三重循环。*/
for (i = 0; i < a;++i) {
		for (j = i + 1; j < a; ++j) {
			for (k = j + 1; k < a; ++k) {
				len = b[i] + b[j] + b[k];
				ma = max(b[i], max(b[j], b[k]));
				ans = len - ma;
				if (ma < ans) { z = max(z, len); }
			}
	}
	}

  • 1.6.2 Ants(POJ No.1852)
    Description
    An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it immediatelly falls off it. When two ants meet they turn back and start walking in opposite directions. We know the original positions of ants on the pole, unfortunately, we do not know the directions in which the ants are walking. Your task is to compute the earliest and the latest possible times needed for all ants to fall off the pole.
/*2只蚂蚁相遇,把它看成相遇后还是沿原方向前行结果也是一样的*/
for (i = 0; i < n; ++i) {
		mint = max(mint, min(x[i], L - x[i]));
	}
for (i = 0; i < n; ++i) {
		maxt = max(maxt, max(x[i], L - x[i]));
	}

  • 1.6.3 抽签问题
    你的朋友提议玩一个游戏,将写有数字的n个纸片放入口袋中,你可以从口袋中抽取4次纸片,每次记下纸片上的数字后都将其放回口袋中,如果这四个数字的和为m,
    就是你赢,否则就是你的朋友赢,你挑战了好几次,结果一次也没有赢,于是撕破口袋,取出所有的纸片,检查自己是否有赢的可能性。
    请编写一个程序,判断当纸片上写的数字是K1,K2,K3,…,Kn 时,是否存在抽取四次和为m的情况,如果存在,输出Yes,若不存在,输出No。
/*如果n在合理范围内,可以直接四重循环穷举(循环:n^4)*/ 
bool f = false;
	for (a = 0; a < n;++a) {
		for (b =0; b < n;++b) {
			for (c = 0; c < n;++c) {
				for (d = 0; d < n;++d) {
					if (k[a] + k[b] + k[c]+k[d]==m) {f = true;}
				}
		     }
		  }
	   }
/*如果n过大,四重循环效率太慢,我们可以用二分搜索算法替换最内侧的循环*/
//循环:n^3logn ;排序:nlogn
bool binary_search(int *a,int n,int key) {
	int low, high,mid;
	bool f = false;
	low = 0;
	high = n;
	while (low <= high) {
		mid = (low + high) / 2;
		if (key < a[mid]) { high = mid - 1; }
		else if (key > a[mid]) { low = mid + 1; }
		else {f = true; break;}
	}
	return f;
}
----------
sort(k,k+n);
bool f = false;
	for (a = 0; a < n;++a) {
		for (b = 0; b < n;++b) {
			for (c =0; c < n;++c) {
if (binary_search(k, n, m - (k[a] + k[b] + k[c])))
                                                 { f = true;}
		     }
		  }
	   }
/*同样道理,我们可以尝试用二分搜索来替换内侧两重循环;(循环:n^2logn;排序:n^2logn)*/
//先将内侧两重循环排好序
for (i = 0; i < n; ++i) {
		for (int j = 0; j < n;++j) {
			kk[i*n+j] = k[i] + k[j];
		} 
	}
	sort(kk,kk+n*n);
//再来搜索
bool f = false;
	for (a = 0; a < n;++a) {
		for (b = 0; b < n;++b) {
				if (binary_search(kk,kk+n*n, m - (k[a] + k[b]))) { f = true; }        
		  }
	   }	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值