zoukankan      html  css  js  c++  java
  • 嘉馨学姐又双叒叕来吃包子了 QDUOJ 模拟 尺度法

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

    点我进入OJ题目详情

    题意

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

    解题思路

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

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

    后来想了想,这个思路不就是使用尺取嘛。

    代码实现

    //尺取,代码更加简洁
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    using namespace std;
    const int maxn = 1e6+7;
    int num[maxn];
    map<int, int> mp;
    int main()
    {
        int n;
        while(scanf("%d", &n) != EOF)
        {
            int ans = 0, l=1;
            mp.clear();
            for (int i = 1; i <= n; i++)
                scanf("%d", &num[i]);
            for (int r = 1; r <= n; r++)
            {
                mp[num[r]]++;
                while(mp[num[r]] > 1)
                {
                    mp[num[l]]--;
                    l++;
                }
                ans = max(r - l +1, ans);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    //这个是自己思路清晰后写的代码,思路将相当与两个指针
    #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
    ", 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
    ", ans);
    	}
    	return 0;
    }
    
    欢迎评论交流!
  • 相关阅读:
    svn: E120106: ra_serf: The server sent a truncated HTTP response body.
    HTTP method POST is not supported by this URL解决
    TinyOS文件结构清单解析
    Crush Course 神话学笔记
    Django 入门
    Crush Course 心理学笔记
    网络相关知识汇总链接
    9.21 小程序开发培训讲座
    论文简读之LAIA
    Android studio 的那些坑
  • 原文地址:https://www.cnblogs.com/alking1001/p/11619400.html
Copyright © 2011-2022 走看看