POJ3349,洛谷SP4354-SnowflakeSnowSnowflakes【最小表示法,hash】
生活随笔
收集整理的這篇文章主要介紹了
POJ3349,洛谷SP4354-SnowflakeSnowSnowflakes【最小表示法,hash】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
洛谷評測記錄:https://www.luogu.org/recordnew/lists?uid=52918&pid=SP4354
POJ題目鏈接:http://poj.org/problem?id=3349
題目大意
有n片雪花,他們6個角有不同的長度,如果兩片雪花6個角長度相同(可以不同方向),那么就是兩片相同的雪花,求第一個相同的雪花。
解題思路
我們可以用hash判斷兩片雪花是否相同,然后用每片雪花的最小表示法,這樣就不需要別的判斷。
code
#include<cstdio> #include<algorithm> #define ymm 160001 #define ull unsigned long long int a[21],ans1,ans2,ans,n; ull h[ymm]; using namespace std; unsigned hash(ull x){unsigned pos=x%ymm,i=0;while (i<ymm&&h[(pos+i)%ymm]&&h[(pos+i)%ymm]!=x) i++;return (pos+i)%ymm; }//哈希表 void small()//最小表示法 {int i=7,j=8,k;while(i<=12&&j<=12){for(k=0;k<=6&&a[i+k]==a[j+k];k++);if(k==6) break;if(a[i+k]>a[j+k]){i+=k+1;if(i==j) i++;}else{j+=k+1;if(i==j) j++;}}//正序ans1=min(i,j);i=12,j=11;while(i>=7&&j>=7){for(k=0;k<=6&&a[i-k]==a[j-k];k++);if(k==6) break;if(a[i-k]>a[j-k]){i-=k+1;if(i==j) i--;}else{j-=k+1;if(i==j) j--;}}//逆序ans2=max(i,j); } bool insert() {small();int ans=ans1,x;bool f=false;ull sum=0;int i;for(i=0;i<6&&a[ans1+i]==a[ans2-i];i++);if(a[ans1+i]>a[ans2-i]) ans=ans2,f=true;//求順時和逆時的最小if(!f)for(i=ans;i<ans+6;i++) sum=sum*13131+a[i];elsefor(i=ans;i>ans-6;i--) sum=sum*13131+a[i];//計算hash值if(h[(x=hash(sum))]==sum) return 1;h[x]=sum;return 0;//判斷 } int main() {scanf("%d",&n);for(int i=1;i<=n;i++){for(int j=7;j<=12;j++) scanf("%d",&a[j]),a[j-6]=a[j+6]=a[j];if(insert()){printf("Twin snowflakes found.");return 0;}}printf("No two snowflakes are alike."); } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的POJ3349,洛谷SP4354-SnowflakeSnowSnowflakes【最小表示法,hash】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 食盐市场属于什么市场 关于盐业的小知识
- 下一篇: P1368-工艺【最小表示法】