STL的应用 POJ 1840 Eqs 题解

题目:

Description

Consider equations having the following form:
a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0
The coefficients are given integers from the interval [-50,50].
It is consider a solution a system (x1, x2, x3, x4, x5) that verifies the equation, xi∈[-50,50], xi != 0, any i∈{1,2,3,4,5}.
Determine how many solutions satisfy the given equation.
Input
The only line of input contains the 5 coefficients a1, a2, a3, a4, a5, separated by blanks.

Output

The output will contain on the first line the number of the solutions for the given equation.

Sample Input

37 29 41 43 47

Sample Output

654
本题直接想到的是“暴力破解法”直接枚举。但是用于方程原型复杂度较高,N^5,N的规模为100,直接算的话要计算100^5次方程,肯定会超时。
所以要将方程做一个变形,变为:
-(a1x13+ a2x23)==a3x33+ a4x43+ a5x53
现在可以暴力破解了,分别把两边的所有取值存入数组(由于本题只要求对解进计数,所以一维就足够了),再作比较。
作暴力破解时,可以把Xi看做互相独立的。所以可以在一个三层的循环中进行,即外面两层循环用来枚举方程左边的值,最里层枚举方程右边的值。
(这样复杂度就变成了N^3.)
破解出方程两边的所有取值之后,接下来就是匹配解了。
有两种策略,一是,由左边的值匹配右边的;另一是,由右边的值匹配左边的。由于需要对被匹配的一边的值序列进行排序,而考虑到整个过程的效率,必须尽可能的使被排序的序列较长(此时效率更高)。所以,左配右的策略更好。
排序,可以用 STL 的 sort ,或者C语言的 qsort;(sort的复杂度是O(NlogN),qsort的最佳效率为O(NlogN))
匹配过程是:对于任意一个左边的取值,如果右边的值集合里有 n 个和它相同的值,则解数目加 n ,所以可以使用 STL 的for_each(),只须自己再完成一个函数,这个函数实现对任意 的一个值,找出它在右边(集合)出现几次。
用STL可以完美的实现。看看AC的源码,就知道STL有多么好用。
 
#include <cstdio>
#include <algorithm>
using namespace std;
#define cub(x) (x*x*x)
int alist[10000], blist[1000000];
int *aend=alist, *bend=blist;
int rescnt=0;
// void printi(int n) { printf("%d\n", n); }
void findroot( int an );
int main()
{
// freopen("aaa.txt","r",stdin);
	int a[5];
	for (int i=0; i<5; i++) scanf("%d", a+i);
	
	for (int i=-50; i<=50; i++) if(i)
		for (int j=-50; j<=50; j++) if(j)
		{
			*(aend++) = -(a[0]*cub(i) + a[1]*cub(j) );
			for (int k=-50; k<=50; k++) if(k){
				*(bend++) = a[2]*cub(i) + a[3]*cub(j) + a[4]*cub(k);
			}
		}
		
	// sort(alist, aend);
	sort(blist, bend);
	// for_each(alist, aend, printi );
	// for_each(blist, bend, printi );
	for_each( alist, aend, findroot );
	printf("%d\n", rescnt);
	return 0;
}

void findroot(int an)
{
	int* ipl = lower_bound(blist, bend, an);
	if (ipl != bend ) {
		for( ; ; ipl++){
			if ( *ipl > an ) return;
			rescnt++;
		}
	}
}

转载于:https://my.oschina.net/u/737017/blog/349617

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值