uva 11572 唯一的雪花 Unique Snowflakes


输入一个长度为n(n<=1e6)的序列A,找到一个尽量长的连续子序列AL~AR,使得该序列中没有相同元素。输出最大长度。


核心是:

对数据处理类似与一个队列的结构,队头front,队尾rear,两个都可以不断增加,比如rear增加1,那么为了保证同一个元素不在队列里出现两次,可能会出队一些元素。


或者可以这么解释,对于每一个值x,记录前一个值x出现的位置last[x],所以考虑x进入序列时,last[x]及以前的元素不得考虑。


具体实现:

数据结构的选择有很多种,不管是用map还是set还是自己定义的结构体都是可以的。


我自己写的稍微麻烦点,离散化+队列处理。

离散化:先排序,然后用存储每个数值的映射值,o(nlogn)。其实这个作法相当于用map作为存储结构。


用set是很自然的想法,因为扫描的顺序是从左往右,所有set只用记录每个元素是否出现即可。



不管是枚举rear所在位置[0,n)还是front所在位置[0,n)都是可以的




/**==========================================
 *   This is a solution for ACM/ICPC problem
 *
 *   @source£º
 *   @type:
 *   @author: wust_ysk
 *   @blog:  http://blog.csdn.net/yskyskyer123
 *   @email: 2530094312@qq.com
 *===========================================*/
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define REP(i,n)  for(int i=0 ;i<(n) ;i++)
using namespace std;
typedef long long ll;
const int INF =0x3f3f3f3f;
const int maxn= 1000000   ;
struct Node
{
    int ind,x,y;
    bool operator<(const Node b)const
    {
        return ind<b.ind;
    }

}a[maxn+4];

bool cmp(Node c,Node b)
{
    return c.x<b.x;
}
int n;

struct MyQueue
{
    int front,rear;
    bool vis[maxn+4];
    void clear()
    {
        front=rear=0;
        memset(vis,0,n*sizeof vis[0]);
    }
    int size()
    {
        return rear-front;
    }
    void push(int y)
    {
        if(!vis[y])
        {
            rear++;
            vis[y]=1;
            return;
        }
        while(a[front].y!=y )
        {
            vis[a[front].y]=0;
            front++;
        }
        front++;
        rear++;

    }

}Q;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        REP(i,n)
        {
            scanf("%d",&a[i].x);
            a[i].ind=i;
        }
        sort(a,a+n,cmp);
        REP(i,n)
        {
            a[i].y=i;
            int t=i;
            while(i+1<n&&a[i+1].x==a[i].x)
            {
                a[++i].y=t;
            }
        }
        sort(a,a+n);
        Q.clear();
        int ans=0;
        REP(i,n)
        {
            int y=a[i].y;
            Q.push(y);
            ans=max(ans,Q.size());
        }
        printf("%d\n",ans);
    }

   return 0;
}


  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

PoemK

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值