嘉馨学姐又双叒叕来吃包子了 QDUOJ 模拟

题意

给你一串数,让你求长度最长的子串,这个字串满足里面没有重复出现的数字。

解题思路

使用一个标记数组,来标记每个数的第一次出现的位置,然后进行下面的模拟,详细看代码实现吧。

自己当时憨憨,没有想到需要进行离散化,第一次提交后返回Runtime Error后立刻意识到需要进心离散化,但是没时间了,哎,太可惜了。当然做这道题时,自己思路也不是很清晰,导致Debug了好长时间。

代码实现

//这个是自己思路清晰后写的代码,思路将相当与两个指针
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1e6+7;
vector<int> v;
int a[maxn], vis[maxn];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        while(!v.empty()) v.pop_back() ; //清空上次的数据
        for(int i=1; i<=n; i++)
            vis[i]=0; //初始化
        for(int i=1; i<=n; i++)
        {
            scanf("%d", &a[i]);
            v.push_back(a[i]);
        }
        sort(v.begin() , v.end() );
        v.erase(unique(v.begin() , v.end() ), v.end() ); //这行和上一行是进行离散化
        for(int i=1; i<=n; i++)
        {
            a[i]=lower_bound(v.begin() , v.end() , a[i])-v.begin()+1;
            if(vis[a[i]]==0)//这里只记录第一次数字出现的位置
                vis[a[i]]=i;
        }
        int i, begin=1, ans=0;//begin相当于左指针
        for(i=1; i<=n; i++)//这里的i相当于右指针
        {
            if(vis[a[i]]!=i)
            {
                if(vis[a[i]] < begin) //如果第一次出现的位置,小于左指针指向的位置,那么就可以直接更改标记数组就行了,这里可以用笔和纸模拟一下就可以了。
                {
                    vis[a[i]]=i;
                }
                else
                {
                    ans=max(ans, i-begin); //i-begin是长度
                    begin=vis[a[i]]+1;//更改左边的位置
                    vis[a[i]]=i; //更改标记数组
                }
            }
        }
        ans=max(ans, i-begin); //这里最后一次也需要进行判断一次
        printf("%d\n", ans);
    }
    return 0;
}
//这里加了离散化就过来,还是自己太菜了!
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
int a[maxn];
int vis[maxn];
vector<int> v;
int main()
{
    int n;
    while(scanf("%d", &n)!=EOF)
    {
        while(!v.empty()) v.pop_back() ;
        for(int i=1; i<maxn; i++)
            vis[i]=0;
        for(int i=1; i<=n; i++)
        {
            scanf("%d", &a[i]);
            v.push_back(a[i]);
        }
        sort(v.begin(), v.end());
        v.erase( unique(v.begin(), v.end() ), v.end() );
        for(int i=1; i<=n; i++)
        {
            int tmp=lower_bound(v.begin(), v.end() , a[i]) - v.begin() +1;
            a[i]=tmp;
            if(vis[tmp]==0)
                vis[tmp]=i;
        }
        int ans=0, tmp=0, begin=1, flag=0;
        for(int i=1; i<=n; i++)
        {
            flag=0;
            if(vis[a[i]]!=i && vis[a[i]]!=0)
            {
                if(vis[a[i]]>=begin)
                {
                    ans=max(tmp, ans);
                    tmp++;
                    if(vis[a[i]]==begin)
                        tmp=tmp-1;
                    else
                        tmp=tmp-vis[a[i]]+begin-1;
                    begin=vis[a[i]]+1;
                    flag=1;
                }
                vis[a[i]]=i;
                if(flag==0)
                    tmp++;
            }
            else{
                tmp++;
            }
        }
        ans=max(ans, tmp);
        printf("%d\n", ans);
    }
    return 0;
}
01-18 16:29