zoukankan      html  css  js  c++  java
  • SP4354 【TWINSNOW

    这题可以哈希。

    可以按照普通的哈希表写,但是插入的时间复杂度比较大还可能被卡单模数哈希。

    考虑将每个雪花特征和对于某一个质数取模的余数分类,对于每一类中的数用循环 (O(n^2)) 判断 。质数取的大一些就可以减小每一类数的个数,从而保证了复杂度。

    关于判断,可以考虑暴力打表,反正没几种情况,而且类似循环展开的还能减小常数。

    
    bool check(int x,int y) {
    	for(rint i=0;i<6;++i) {
    		if(a[x][0]==a[y][i]&&a[x][1]==a[y][(i+1)%6]
    		 &&a[x][2]==a[y][(i+2)%6]&&a[x][3]==a[y][(i+3)%6]
    		 &&a[x][4]==a[y][(i+4)%6]&&a[x][5]==a[y][(i+5)%6])return 1;//顺时针
    		if(a[x][0]==a[y][i]&&a[x][1]==a[y][(i+5)%6]
    		 &&a[x][2]==a[y][(i+4)%6]&&a[x][3]==a[y][(i+3)%6]
    		 &&a[x][4]==a[y][(i+2)%6]&&a[x][5]==a[y][(i+1)%6])return 1;//逆时针
    	}
    	return 0;
    }
    

    关于取什么模数好:
    尽量把每个雪花分散开,所以取 (n) 左右。我取了99991,珂以通过.但是很显然可以卡成 (O(n^2))。。。

    还有一种方法,就是随机一个模数出来,这样就几乎不可能卡了。有一种方法(自己yy的,可能有更好的方法):先随机一个在指定范围内的数,然后判断是否为质数。不是就加一接着判断。由于质数比较密集,复杂度可以保证。

    这部分的代码大概长这样

    
    	srand(time(0));
    	mod=rand()*3+20000;
    	while(mod<90000||mod>100000)mod=rand()*3+20000;
    	while(!isprime(mod))++mod;
        
    

    由于区间跨度是10000,有3333种rand到的数可以在这个区间,rand的值域是32768,概率大概是 (dfrac{1}{10}) ,很快就可以rand到区间内。

    这种随机模数的方法550ms,第4页。直接取99991是460ms,第3页,跑的应该不算慢了,而且码量不大,没压行60行不到。

    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    using namespace std;
    #define rint register int
    typedef long long LL;
    inline int rd(){
       int x=0,f=1;
       char ch=getchar();
       while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
       while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
       return x*f;
    }
    int mod;
    const int N=120010;
    int a[N][7],n;
    vector<int>v[N];
    bool check(int x,int y) {
    	for(rint i=0;i<6;++i) {
    		if(a[x][0]==a[y][i]&&a[x][1]==a[y][(i+1)%6]
    		 &&a[x][2]==a[y][(i+2)%6]&&a[x][3]==a[y][(i+3)%6]
    		 &&a[x][4]==a[y][(i+4)%6]&&a[x][5]==a[y][(i+5)%6])return 1;
    		if(a[x][0]==a[y][i]&&a[x][1]==a[y][(i+5)%6]
    		 &&a[x][2]==a[y][(i+4)%6]&&a[x][3]==a[y][(i+3)%6]
    		 &&a[x][4]==a[y][(i+2)%6]&&a[x][5]==a[y][(i+1)%6])return 1;
    	}
    	return 0;
    }
    bool isprime(int n){
    	if(n==1)return false;
    	if(n==2||n==3||n==5)return true;
    	if(n%6!=1&&n%6!=5)return false;
    	for(int i=5,mx=sqrt(n);i<=mx;++i)
    	if((n%i==0)||(n%(i+2)==0))return false;
    	return true;
    }
    int main() {
    	srand(time(0));
    	mod=rand()*3+20000;
    	while(mod<90000||mod>100000)mod=rand()*3+20000;
    	while(!isprime(mod))++mod;
    	//mod=99991; 
    	n=rd();
    	for(rint i=0;i<n;++i)
    		for(rint j=0;j<6;++j)
    			a[i][j]=rd();
    	long long sum;
    	for(rint i=0;i<n;++i) {
    		sum=0;
    		for(rint j=0;j<6;++j)sum+=a[i][j];
    		sum%=mod;
    		for(rint j=0;j<v[sum].size();++j)
    			if(check(i,v[sum][j]))return puts("Twin snowflakes found."),0;
    		v[sum].push_back(i);
    	}
    	return puts("No two snowflakes are alike."),0;
    }
    
    路漫漫其修远兮,吾将上下而求索
  • 相关阅读:
    现代软件工程 第一章 概论 第3题——韩婧
    现代软件工程 第一章 概论 第2题——韩婧
    小组成员邓琨、白文俊、张星星、韩婧
    UVa 10892 LCM的个数 (GCD和LCM 质因数分解)
    UVa 10780 幂和阶乘 求n!中某个因子的个数
    UVa 11859 除法游戏(Nim游戏,质因子)
    Codeforces 703C Chris and Road 二分、思考
    Codeforces 703D Mishka and Interesting sum 树状数组
    hdu 5795 A Simple Nim SG函数(多校)
    hdu 5793 A Boring Question 推公式(多校)
  • 原文地址:https://www.cnblogs.com/zzctommy/p/12918536.html
Copyright © 2011-2022 走看看