• 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++;
    		}
    	}
    }

     
     
  • 相关阅读:
    苹果开发者账号注册申请(二)
    css3 media媒体查询器用法总结
    CSS,font-family,好看常用的中文字体
    行内元素和块级元素
    苹果开发者账号注册申请(一)
    web前端利用leaflet生成粒子风场,类似windy
    激光雷达--看图
    linux screen 多任务后台执行
    linux 系统监控和进程管理
    linux下postgresql的连接数配置
  • 原文地址:https://www.cnblogs.com/xusw/p/5205874.html
Copyright © 2020-2023  润新知