ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 Luogu P3370

2019-10-02 10:52:45  阅读:169  来源: 互联网

标签:string int 题解 ++ Luogu bool ull ans P3370


讲讲这题的几种做法:

暴力匹配法

rt,暴力匹配,即把字符串存起来一位一位判相等

时间复杂度$ O(n^2·m) $

再看看数据范围

$n\le10^5,m\le10^3$

当场爆炸。当然有暴力分

代码(20pts):

#include <bits/stdc++.h>
using namespace std;
char c[100001][1001];
bool pd(int x, int y)
{
    int l1 = strlen(c[x]), l2 = strlen(c[y]);
    if(l1 != l2) return 0;
    for(int i = 0; i < l1; i++)
    {
        if(c[x][i] != c[y][i]) return 0;
    }
    return 1;
}
int main()
{
    int n;
    cin >> n;
    int ans = n;
    for(int i = 1; i <= n; i++)
    {
        cin >> c[i];
        for(int j = 1; j < i; j++)
        {
            if(pd(i, j)) ans--;
        }
    }
    cout << ans;
    return 0;
}

好漂亮呀

好漂亮呀

不要问我为什么WA了,我也没想调

string法

比较正常的方法

思路就是把所有串存下来,用string自带的运算符(大于等于小于)进行字典序排序

然后按照字典序判断是否重复即可

时间复杂度嘛

$O(n·logn)$的,可以

代码(100pts):

#include <bits/stdc++.h>
using namespace std;
string s[10001];
int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> s[i];
    }
    sort(s + 1, s + n + 1);//因为string自带大于和小于所以不用cmp
    int ans = n;
    for(int i = 1; i < n; i++)
    {
        if(s[i] == s[i + 1]) ans--;
            //若两个字符串相同则他们的字典序一定是相邻的
    }
    cout << ans;
    return 0;
}

C++STL法

我们当然可以用万能的STL做啦~

先来思考:我们判断一个数字是否重复是什么方法呢?

当然是bool used[1001] 啦

而这题要求判断的是字符串怎么办

把数组下标弄成string类型呗

请出主角:map

简单来讲,我们在定义数组时,只能确定数组中数的类型(比如char、bool、int、long long等等),而下标类型是固定的,即整数型

然而map可以确定这两个类型,也就是说,我们甚至可以把字符串作为下标,数字作为基本类型,来一个“反数组”(别问我反数组是啥,字面意思)

(那是不是要写成$a_{interesting} = 3$了)

那么结合上上上上上上上句话,这题就可做啦!

时间复杂度不明 反正能过就是了

代码(100pts):

#include <bits/stdc++.h>
using namespace std;
map < string , bool > m;//定义一个以string类型为下标的bool数组
string s;
int main()
{
    int n;
    cin >> n;
    int ans = n;
    for(int i = 1; i <= n; i++)
    {
        cin >> s;
        if(m[s]) ans--;
        else m[s] = 1;
    }
    cout << ans;
    return 0;
}

比暴力短

HASH法

不要问为什么是最后,你见过哪个游戏让你一开始就打BOSS的?

这个和C++STL法有异曲同工之妙 说反了吧

既然字符串当不了下标,我们就把字符串转成数字嘛。

具体请看那个有几百个赞的dalao的题解吧(~~orz@_皎月半洒花%%%%%%~~)

代码(单hash,100pts):

#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
ull base = 131;
ull a[100001];
char c[10001];
ull hashe(char s[])
{
    int l = strlen(s);
    ull ans = 0;
    for(int i = 0; i < l; i++)
    {
        ans = (ans * base + (ull)(s[i])) % 200408020617;
    }
    return ans;
}
int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> c;
        a[i] = hashe(c);
    }
    sort(a + 1, a + n + 1);
    ull ans = 1;
    for(int i = 1; i < n; i++)
    {
        if(a[i] != a[i + 1]) ans++;
    }
    cout << ans;
    return 0;
}

注:模数只写阳历生日太短会被卡?那就把 女朋友的 阴历生日加在后面鸭

标签:string,int,题解,++,Luogu,bool,ull,ans,P3370
来源: https://www.cnblogs.com/H2SO4/p/11616952.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有