zoukankan      html  css  js  c++  java
  • [最小表示]PKU 3349 Snowflake Snow Snowflakes

    最小表示法 + 排序 + 枚举, 整体复杂度:O(n*lgn*6)

    这道题普通的枚举就可以做,hash 和枚举差不多,繁琐的地方都在判断是否同构那里,我干脆用最小表示法把原串转换为原串的最小表示和反串的最小表示中的较小者,然后排序,枚举相邻的位置的串是否相等;

    最小表示法的一点更正:这篇博文中作者做了一个优化,我以前是参考优化后的做法写的,现在发现评论中有人提到了一个问题(最小位置直接出现在对升序序列后的情况下,这个优化实际上使复杂度变为了O(n^2),已经验证),把 j 减少到 i+1 不合理,所以又回到了原始的做法,具体见代码。

    # include <stdio.h>
    # include <string.h>
    # include <stdlib.h>
    
    # define N 100005
    
    int n;
    int a[N][6];
    /*******************************************/
    int mr(int *v, int nn)
    {
        int i = 0, j = 1, cnt = 0, t;
            
        while (i<nn && j<nn && cnt<nn)    
        {
            t = v[(i+cnt)%nn] - v[(j+cnt)%nn];
            if (!t) ++cnt;
            else
            {
                if (t > 0)  i = i+cnt+1;
                else j = j+cnt+1;
                if (i == j) ++j;
                cnt = 0;   
            }
        }
        return i<j ? i:j;
    }
    
    /*******************************************/
    int acmp(int *s, int *t)
    {
        int i;
        for (i = 0; i < 6; ++i)
            if (s[i] < t[i]) return -1;
            else if (s[i] > t[i]) return 1;
        return 0;
    }
    
    void process(int *t, int k)
    {
        int i, u[6], v[6], s, tmp;
        s = mr(t, 6);
        for (i = 0; i < 6; ++i)
            u[i] = t[(s+i)%6];
        for (i = 0; i < 3; ++i)
        {
            tmp = t[i];
             t[i] = t[5-i];
              t[5-i] = tmp;
         }       
        s = mr(t, 6);
        for (i = 0; i < 6; ++i)
             v[i] = t[(s+i)%6];
        if (acmp(u, v) < 0)
             memcpy(a[k], u, sizeof(int)*6);
        else
             memcpy(a[k], v, sizeof(int)*6);
    }
    /*******************************************/
    int cmp(const void *xx, const void *yy)
    {
        int i, *x = (int*)xx, *y = (int *)yy;
        for (i = 0; i < 6; ++i)
            if (*(x+i) < *(y+i)) return -1;
            else if (*(x+i) > *(y+i)) return 1;
        return 0;
    }
    
    void solve(void)
    {
        int i, j, t[6], found = 0;
        for (i = 0; i < n; ++i)
        {
            for (j = 0; j < 6; ++j)
                scanf("%d", &t[j]);
            process(t, i);
        }
        qsort(a, n, sizeof(a[0]), cmp);
        for (i = 1; i < n; ++i)
        {
            if (acmp(a[i], a[i-1]) == 0)
            {
                 found = 1;
                 break;
              }       
        }
        puts(found ? "Twin snowflakes found.":"No two snowflakes are alike.");
    }
    /*******************************************/
    
    int main()
    {
        while (~scanf("%d", &n))
            solve();
        
        return 0;
    }


     

  • 相关阅读:
    SAP一些学习网址
    Silverlight RIA Servcie 删除子对象实体提交错误的问题[解决]
    Clean up your BizTalk databases
    Silverlight RIA Service开发实战总结(一)
    Silverlight ToolKitAutoCompleteBox bug(Style bug)
    domaincontext load 回调
    数据驱动开发For Silverlight WCF RIA1.0 三步曲
    xpath 查询忽略大小
    代码重构之没有理由拒绝Lambda表达式
    离写出大师级代码只差这一步
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2653399.html
Copyright © 2011-2022 走看看