日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDOJ1496 Equations【Hash】

發(fā)布時間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDOJ1496 Equations【Hash】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目大意:

有一個等式,

a*x1^2+b*x2^2+c*x3^2+d*x4^2=0,

a、b、c、d是[-50,50]之間的非零整數,

有一組解析(x1,x2,x3,x4),其中xi是[-100,100]之間的非零整數,

求有多少組解滿足上式;

輸入:多組測試用例,每組測試用例包含4個數:a,b,c,d,他們之間用一個或多個空格隔開,EOF結尾;

輸出:每組測試用例解的個數;

==========基本思路=========

4個循環(huán)嵌套,回溯;但是這樣的復雜度是n^4,在本題中就是10000 0000數量級的~

==========改進思路=========

把兩項移到右邊,就變成了左邊兩項與右邊兩項相等的式子;

這樣只要分別計算左右兩邊相等的可能性即可,這樣的復雜度就是10000數量級了~

==========================

a*x1^2 最大是50*10000 = 500000,其他三項也是,同理,最小是-500000;

兩項的最大就是1000000,最小就是-1000000,這樣就需要一個2000000的hash表來存儲了;

但是要注意的是,最后hash表中存儲的解得個數并不是最后結果,因為a、b、c、d四項可以互換位置,所以最后要乘以2^4 = 16才是解的個數;

Problem :?1496 ( Equations )?????Judge Status :?Accepted
RunId : 7413352????Language : C????Author :?qq1203456195
Code Render Status :?Rendered By HDOJ C Code Render Version 0.01 Beta

?

#include <stdio.h> #include <string.h>int arr[101]; int hash[2000003]; int main() {int a,b,c,d;int i,j,sum;for (i=1;i<101;i++) arr[i] = i*i;while (scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF){if ((a>0 && b>0 && c>0 && d>0) ||(a<0 && b<0 && c<0 && d<0)){printf("0\n");continue;}memset(hash,0,sizeof(hash));for (i=1;i<=100;i++){for (j=1;j<=100;j++){hash[a*arr[i] + b*arr[j] + 1000000]++;}}sum = 0;for (i=1;i<=100;i++){for (j=1;j<=100;j++){sum += hash[-(c*arr[i] + d*arr[j]) + 1000000];}}printf("%d\n",sum<<4);}return 0; }

?=======再次改進=======

很明顯,雙重循環(huán)最多產生10000個數,所以開2000000個空間的數組明顯是浪費了,怎樣優(yōu)化呢?1、數組,2、hash函數,3、沖突處理

開小數組是必須的,但是并不是越小越好,因為還要考慮沖突的現(xiàn)象,但是具體取多少的?HDUACM的課件中開的是50021,這是一個較大的素數,這樣key的位置就可以通過比較常用的除模取余方法來確定了。其實hash函數以及處理沖突的方法有很多,沒有固定的方法。

下邊是HDUACM課件中使用的方法:

int hash(int k) {int t=k%MAX;if(t<0)t+=MAX;while(f[t]!=0&&g[t]!=k)t=(t+1)%MAX;return t; }

hash函數:t = k%MAX

處理沖突的方法:t = (t+1)%MAX

完整代碼:f數組用來統(tǒng)計個數,g數組用來記錄值;

// by laili #include<stdio.h> #include<memory.h>#define MAX 50021int f[MAX],g[MAX];int hash(int k) {int t=k%MAX;if(t<0)t+=MAX;while(f[t]!=0&&g[t]!=k)t=(t+1)%MAX;return t; }int main() {int a,b,c,d,p,i,j,s,n,t[101];for(i=1;i<=100;i++)t[i]=i*i;while(scanf("%d%d%d%d",&a,&b,&c,&d)>0){……} }

while中代碼:

if(a>0&&b>0&&c>0&&d>0||a<0&&b<0&&c<0&&d<0){printf("0\n");continue;}memset(f,0,sizeof(f));n=0;for(i=1;i<=100;i++)for(j=1;j<=100;j++){s=a*t[i]+b*t[j];p=hash(s);g[p]=s;f[p]++;}for(i=1;i<=100;i++)for(j=1;j<=100;j++){s=-(c*t[i]+d*t[j]);p=hash(s);n+=f[p];}printf("%d\n",n*16);

?


本文轉自ZH奶酪博客園博客,原文鏈接:http://www.cnblogs.com/CheeseZH/archive/2012/12/18/2824091.html,如需轉載請自行聯(lián)系原作者

總結

以上是生活随笔為你收集整理的HDOJ1496 Equations【Hash】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。