HDU 1894 String Compare (排序)

String Compare

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)

Total Submission(s): 3124    Accepted Submission(s): 740

Problem Description

Maybe there are 750,000 words in English and some words are prefix of other words, for example: the word "acm" can be treat as one prefix of "acmicpc". What‘s more, most of such pairs of words have relationship between them. Now give you a dictionary, your
work is to tell me how many such pairs.

There may be other characters in the word, for example ‘_‘,‘-‘,and so on.

Pay attention that ‘A‘ and ‘a‘ are not the same character!

Input

In the first line of the input file there is an Integer T, which means the number of test cases. Followed by T test cases.

For each test case, in the first line there is an integer N(0<N<=50000), followed N lines, each contains a word whose length is less than 30 and no space appears in any word. There are no same words in two different lines.

Output

For each test case, tell me how many such pairs. If the number is larger than 11519, just divide it by 11519 and only output the remainder.

Sample Input

2
2
acmicpc
acm
3
a
abc
ab

Sample Output

1
3

这道题败在了超时上面,一开始是用vector,string,很显然,是得用cin,结果超时了

后来,改用cin,结果还是超时,原因是既然是排好序了,那么一旦不匹配了,后面的字符串,都不需要比较了

结果,不超时了,改WA了,又是怎么回事呢?

If the number is larger than 11519, just divide it by 11519 and only output the remainder.

问题在上面,不该直接ans%11519 。。。擦好好读题以后

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
typedef struct node{
    char a[50];
}node;
node s[50010];
void swap(node *a,node *b){
    char t[50];
    strcpy(t,a->a);
    strcpy(a->a,b->a);
    strcpy(b->a,t);
}
int partition(node a[],int l,int h){
    int i=l;
    int j=h+1;
    node v=a[l];
    while(true){
        while(strcmp(a[++i].a,v.a)<0)if(i==h)break;
        while(strcmp(a[--j].a,v.a)>0)if(j==l)break;
        if(i>=j)break;
        swap(&a[i],&a[j]);
    }
    swap(&a[l],&a[j]);//i停留的位置是比partition大的,j是小的
    return j;
}
void quick_sort(node a[],int l,int h){
    if(h<=l)return ;
    int j= partition(a,l,h);
    quick_sort(a , l , j-1);
    quick_sort(a , j+1 , h);
}
bool cmp(node a1,node b1)
{
    return strcmp(a1.a,b1.a)<0;
}
int main(int argc, char *argv[])
{
    //freopen("1894.in","r",stdin);
    int T;
    int N;
    scanf("%d",&T);
    int ans=0;
    int len;
    int k;
    while(T--){
        ans=0;
        scanf("%d",&N);
        for(int i=0;i<N;++i){
            scanf("%s",s[i].a);
        }
        //sort(s,s+N,cmp);
        quick_sort(s , 0, N-1);
        for(int i=0;i<N;++i)
        {
            len=strlen(s[i].a);
            for(int j=i+1;j<N;++j)
            {
                for(k=0;k<len;++k)
                {
                    if(s[i].a[k]!=s[j].a[k])break;
                }
                if(k==len)
                    ans++;
                else break;//后面的都不可能匹配了
            }
        }
         if(ans>11519) ans=ans%11519;
         printf("%d\n",ans);
    }
    return 0;
}

再次比较下自己写的快排和STL的sort的差距

自己写的:

STL的:

时间: 2024-10-11 01:33:50

HDU 1894 String Compare (排序)的相关文章

STL || HDU 1894 String Compare

如果一个词包含再另一个词的前面(前缀),是一对前缀,求一共有多少对 *解法:STL万岁 #include<string>:https://www.cnblogs.com/SZxiaochun/p/6699450.html #include <iostream> #include <cstdio> #include <string> #include <algorithm> using namespace std; #define SZ 50010

hdu 2647 Reward (拓扑排序分层)

Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3815    Accepted Submission(s): 1162 Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wa

快速排序 VS compare排序

为了方便  ,我把bean写成了内部类 测试结论 ,快速排序吊打compare排序 ,可以自行测试 1 //测试调用 2 public static void main(String[] args) { 3 List<Student> list = new ArrayList<Student>(); 4 new test().add(list); 5 //记录旧数据 确定俩次排序使用的是同一数据 6 List<Student> stus = new ArrayList&

hdu 4909 String(计数)

题目链接:hdu 4909 String 题目大意:给定一个字符串,由小写字母组成,最多包含一个问号,问号可以表示空或者任意一个字母.问有多少个子串,字母出现的次数均为偶数. 解题思路:因为最多又26个字母,对应每个字母的奇数情况用1表示,偶数情况用0.将一个前缀串表示成一个二进制数.然后对于每种相同的数s,任选两个即为一种可行子串(组合数学). 接着对于有问号的情况枚举一下问号替代的字符,然后对于问号后面的状态都要再加上一个该字符.这时计算个数时就要将前后分开讨论了. 这题交C++,结果卡FS

hdu 4938 Seeing People 排序+二分查找

Seeing People Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 241    Accepted Submission(s): 61 Problem Description There are two kinds of people. If person i is the first kind of people, it

hdu 1070(结构体排序)

Milk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13639    Accepted Submission(s): 3328 Problem Description Ignatius drinks milk everyday, now he is in the supermarket and he wants to choose

HDU 4917 Permutation 拓扑排序的计数

题意: 一个有n个数的排列,给你一些位置上数字的大小关系.求合法的排列有多少种. 思路: 数字的大小关系可以看做是一条有向边,这样以每个位置当点,就可以把整个排列当做一张有向图.而且题目保证有解,所以只一张有向无环图.这样子,我们就可以把排列计数的问题转化为一个图的拓扑排序计数问题. 拓扑排序的做法可以参见ZJU1346 . 因为题目中点的数量比较多,所以无法直接用状压DP. 但是题目中的边数较少,所以不是联通的,而一个连通块的点不超过21个,而且不同连通块之间可以看做相互独立的.所以我们可以对

hdu 6194 string string string(后缀数组)

题目链接:hdu 6194 string string string 题意: 给你一个字符串,给你一个k,问你有多少个子串恰好在原串中出现k次. 题解: 后缀数组求出sa后,用height数组的信息去找答案. 每次用k长度的区间去卡height数组,求出该区间的lcp. 该区间的贡献就是ans=lcp-max(height[i],height[i+k]). 如果ans<=0,就不贡献. 比如 2 aaa 后缀数组为: 1 a 2 aa 3 aaa height为 0,1,2 现在扫到[1,2],

hdu 4821 String(字符串hash)

题目链接:hdu 4821 String 题意: 给你一个字符串,问你有多少子串,满足长度为m*len,并且这个子串能分成m个len长度的不同串. 题解: BKDRhash+map来判重.注意的是要以len长分类来扫,这样才不会超时. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef unsigned long long ull; 5 co