zoukankan      html  css  js  c++  java
  • Hdu 1496 Equations

    Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1496

    此题可以用哈希数组求解,至于什么是哈希,可以先看以下这篇推荐文章,写得挺不错的。

    推荐:http://www.cnblogs.com/yangecnu/p/Introduce-Hashtable.html#undefined

    方法一:a*x1^2+b*x2^2+c*x3^2+d*x4^2=0

    可以看作:a*x1^2+b*x2^2 = (c*x3^2+d*x4^2)*(-1)

    其中:a,b的大小都在正负50之间,而x则为正负100之间(除了0)

    那么左边的大小范围+-1000000,其实右边也一样。

    那么就可以用两个hash数组,假设为hash1[], hash2[]

    直接将计算结果作为key,那hash1[ key ] 不等于0 时,就代表左边可以计算出key这个值,

    hash2[key]如果也不等于0,也就是右边也可以计算出这个值,即间接说明等式a*x1^2+b*x2^2+c*x3^2+d*x4^2=0成立

    但此时key可能为负数,所以为了更好的与数组配合,两边同加上一个数字2000000,这样两边既能保持平衡,又能使任一边计算结果不为0

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    const int MAXN = 2000000;
    int hash1[ MAXN+5];
    int hash2[ MAXN+5];
    const int CUR = 1000000;
    
    int main()
    {
        int a, b, c, d;
        int i, j;
        int cases=0;
        while( scanf("%d%d%d%d", &a,&b,&c,&d)!=EOF )
        {
        	// a,b,c,d都大于0或都小于0的情况可以直接得出结果为0
            if( a>0 && b>0 && c>0 && d>0 )
            {
                printf("0
    ");
                continue;
            }
            if( a<0 && b<0 && c<0 && d<0 )
            {
                printf("0
    ");
                continue;
            }
           // 数组初始化
            memset( hash1, 0, sizeof(hash1) );
            memset( hash2, 0, sizeof(hash2) );
    
            for( i=1;i<=100;i++ )
            {
                for( j=1;j<=100;j++ )
                {
                    hash1[ i*i*a + j*j*b + CUR ]++;
                    hash2[ CUR - i*i*c - j*j*d ]++;
                }
            }
    
            cases = 0;
            for( i=0;i<=MAXN+3;i++ )
                cases = cases + hash1[i] * hash2[i];
            printf( "%d
    ", cases*16 );
            // 要乘以16 ,因为刚才计算时,x1,x2,x3,x4都只算了为正的情况,但这4个变量其实每个都可正可负的
        }
    }
    

     

     

    方法二:其实也差不多,但主要在空间的利用上,因为x1^2最多有100种情况, x2^2也最多有100种情况,那么每边最多有10000种情况,那么上一种方法对空间实在是太浪费了。所以构造一个好的哈希函数,能节省好多空间。

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    
    using namespace std;
    
    const int PRIME = 9973;
    const int KEEP_POS_MAXN = 2000000;
    const int ARRAY_MAXN = 10000;
    
    typedef struct Node{
    		Node *next;
    		int value;
    		int times;
    		Node(){
    			times = 1;
    			next = NULL;
    		}
    }Node;
    
    Node hash[ARRAY_MAXN];
    
    int GetKey( int value );
    void InsertValue( int value );
    Node *QueryValue( int value );
    void FreeNode( Node * );
    
    int main() {
    	int a, b, c, d;
    	while( scanf( "%d%d%d%d", &a, &b, &c, &d )!=EOF ) {
    		// a,b,c,d 都大于0或都小于0可以直接得出结果为0
    		if( a>0 && b>0 && c>0 && d>0 ) {
    			printf( "0
    " );
    			continue;
    		}
    		if( a<0 && b<0 && c<0 && d<0 ) {
    			printf( "0
    " );
    			continue;
    		}
    		
    		
    		int x1, x2;
    		for( x1=1; x1<=100; x1++ ) {
    			for( x2=1;x2<=100;x2++ ) {
    				InsertValue( a*x1*x1+b*x2*x2+KEEP_POS_MAXN );
    			}
    		}
    		int x3, x4;
    		int total = 0;
    		Node *target = NULL;
    		for( x3=1; x3<=100; x3++ ) {
    			for( x4=1;x4<=100;x4++ ) {
    				target = QueryValue( (c*x3*x3+d*x4*x4)*(-1)+KEEP_POS_MAXN );
    				if( target != NULL ) {
    					total += target->times;
    				}
    			}
    		}
    		printf( "%d
    ", total*16 );	
    		for( int i=0; i<ARRAY_MAXN; i++ ) {
    			// 释放洁点空间的操作,不使用也能AC;但使用与不使用的空间使用情况差距会很大
    			FreeNode( hash[i].next );
    			hash[i].next = NULL;
    		}
    	}
    	return 0;
    }
    
    int GetKey( int value ) {
    	return value % PRIME;
    }
    
    void InsertValue( int value ) {
    	int key = GetKey( value );
    	Node *target = &hash[ key ];
    	while( target->next != NULL ) {
    		target = target->next;
    		if( target->value == value ) {
    			target->times ++;
    			return ;
    		}
    	}
    	
    	Node *node = new Node;
    	node->value = value;
    	target -> next = node;
    	return ;
    	
    }
    
    Node *QueryValue( int value ) {
    	int key = GetKey( value );
    	Node *target = &hash[ key ];
    	
    	do{
    		target = target->next;
    	}while( target!=NULL && target->value!=value );
    	
    	return target;
    }
    
    void FreeNode( Node *target ) {
    	if( target!=NULL ) {
    		FreeNode( target->next );
    		delete target;
    	}
    	return ;
    }
    
  • 相关阅读:
    服务管理器
    自动启动管理器
    进程管理器
    进程模块查看器
    无DLL远程注入
    远程DLL注入
    U盘免疫
    WSAAsyncSelect Demo
    select Demo
    校正系统时间
  • 原文地址:https://www.cnblogs.com/Emerald/p/4280496.html
Copyright © 2011-2022 走看看