zoukankan      html  css  js  c++  java
  • POJ 3865

    【题意】

    给一个字符串组成的矩阵,规模为n*m(n<=10000,m<=10),如果某两列中存在两行完全相同,则输出NO和两行行号和两列列号,否则输出YES

    【题解】

    因为m很小,所以对每一行枚举其中两个字符串,检查之前行中对应的两列里是否重复即可。但是如何判重。

    一开始想的把字符串做成pair然后用map映射为行号,但是TLE。

    后来想到用hash判重,可能是因为哈希函数不够好,还是TLE。。。

    总之这道题卡了三个小时,一直TLE。

    枚举每一列,对枚举到的那一列从小到大排序,然后找到相邻两个相等的,接着在相同行,不同列中寻找相等的字符串,如果存在表示找到解。复杂度是m^2*n*logn,处于可以接受的范围。

    最后的方法在POJ上使用C++通过,但是G++却超时了。

    曾经记得POJ有一道题是使用G++通过,C++超时,总之以后在POJ上超时了就两个编译器都试试。

    在看别人的代码时,发现有人用了字符串hash读入:

    typedef unsigned long long ULL;
    ULL hash(char *s) {
        ULL res = 0;
        for(int i = 0; s[i]; ++i) {
            res *= 9837;//质数
            res += s[i];
        }
        return res;
    }

    这样做比较速度相当快,程序用时不到1s。

    因为没有处理冲突,所以可以用这个方法水过去(笑)

    代码:(没有用字符串hash)

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<string>
    #include<sstream>
    #define eps 1e-9
    #define ALL(x) x.begin(),x.end()
    #define INS(x) inserter(x,x.begin())
    #define FOR(i,j,k) for(int i=j;i<=k;i++)
    #define MAXN 1005
    #define MAXM 40005
    #define INF 0x3fffffff
    using namespace std;
    typedef long long LL;
    int i,j,k,n,m,x,T,ans,big,cas,num,len,nodenum,l;
    bool flag;
    char s[105],t[105];
    int pre;
    string y[10005][15];
    
    
    string ex;
    struct node
    {
        string st;
        int i;
    } G[10005];
    
    bool cmp(node a,node b)
    {
        return a.st<b.st;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        gets(s);
        for (i=1;i<=n;i++)//读入
        {
            gets(s);
            len=strlen(s);
            s[len]=',';
            s[len+1]='';
            pre=0;
            num=0;
            for (j=0;j<=len;j++)
            {
                if (s[j]==',')
                {
                    s[j]='';
                    y[i][++num]=(s+pre);
                    
                    pre=j+1;
                }
            }
        } 
            
        for (i=1;i<=m;i++)//枚举列
        {
            for (j=1;j<=n;j++)//把这一列复制一遍后排序
            {
                G[j].st=y[j][i];
                G[j].i=j;
            }
            sort(G+1,G+1+n,cmp);
            
            
            for (j=1;j<=n;j++)//枚举行
            {
                for (k=j+1; k<=n && G[k].st==G[j].st ;k++)//向下找与第j行相同的行
                {
                    for (l=i+1;l<=m;l++)//再枚举其他列,检查是否有重复
                    {
                        if ( y[ G[j].i ][l]==y[ G[k].i ][l] )//存在重复
                        {
                            printf("NO
    ");
                            printf("%d %d
    ",G[j].i,G[k].i);
                            printf("%d %d
    ",i,l);
                            return 0;
                        }
                    }
                }
            }
        }
            
        printf("YES
    ");
        return 0;
    }
  • 相关阅读:
    DB2基本语句操作
    makefile简析与例子
    io多路复用epoll归纳
    Selenium 3----设置元素等待
    Selenium 3----获取断言信息
    Selenium 3----鼠标、键盘操作常用方法
    Selenium 3----WebDriver常用方法
    算法时间复杂度求解
    Selenium 3----控制浏览器操作
    操作系统基础知识学习
  • 原文地址:https://www.cnblogs.com/zhyfzy/p/4271664.html
Copyright © 2011-2022 走看看