Snowflake Snow Snowflakes

题目:http://poj.org/problem?id=3349

给你N串数字,每串由六个数字组成,让你求这其中有没有相似的六个数字。比如:
1 2 3 4 5 6
3 4 5 6 1 2
5 4 3 2 1 6
都是相似的。因为范围比较大,可以用hash记录。记录时将和相同的的六个数字记录在一起可以减少时间复杂度。最后对vector进行遍历,如果size大于1说明有可能有相似的。将有可能的拿出来进行比较就行了。
这道题做的时候是卡着边过的,用G++会TLE,用C++就能AC。

#include <iostream>
#include <vector>
#include <cstdio>
#define NUM  100000
#define LONG 10000000
using namespace std;

typedef struct node{
    int bian[6];
}snow[NUM];

vector<node>hs[NUM];

void hash_(node tt){
    int no = 0;
    for(int i = 0; i < 6; i++){
        no += tt.bian[i];
    }
    no = no % NUM;
    hs[no].push_back(tt);
}

bool cmp(node s1, node s2){
    for(int i = 0; i < 6; i++){
        if(s1.bian[i] == s2.bian[0] && s1.bian[(i+1)%6] == s2.bian[1] && s1.bian[(i+2)%6] == s2.bian[2] \
                && s1.bian[(i+3)%6] == s2.bian[3] && s1.bian[(i+4)%6] == s2.bian[4] && s1.bian[(i+5)%6] == s2.bian[5]){
            return true;
        }
        if(s1.bian[i] == s2.bian[5] && s1.bian[(i+1)%6] == s2.bian[4] && s1.bian[(i+2)%6] == s2.bian[3] \
                && s1.bian[(i+3)%6] == s2.bian[2] && s1.bian[(i+4)%6] == s2.bian[1] && s1.bian[(i+5)%6] == s2.bian[0]){
            return true;
        }
    }
    return false;
}

int main(){
    ios::sync_with_stdio(false);
    int n;
    node tt;
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        for(int j = 0; j < 6; j++){
            scanf("%d", &tt.bian[j]);
        }
        hash_(tt);
    }

    for(int i = 0; i < NUM; i++){
        if(hs[i].size() <= 1){
            continue;
        }
        for(int j = 0; j < hs[i].size(); j++){
            for(int k = j + 1; k < hs[i].size(); k++){
                if(cmp(hs[i][j], hs[i][k])){
                    printf("Twin snowflakes found.\n");
                    return 0;
                }
            }
        }
    }

    printf("No two snowflakes are alike.\n");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值