您的位置:首页 > 产品设计 > UI/UE

UVALive 5881 Unique Encryption Keys

2015-08-07 11:17 330 查看
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3892

题意:给出有n个数的序列,进行m次询问,每次询问给出一个区间[l,r],问区间中是否有重复的数

思路:把整个序列进行一次预处理,求出与第i个数相等且排在它前面的数保存在pr[i],最后询问时枚举区间每一个数,比较pr[i]与l的大小,题目给的时间比较宽松,所以水过去了,更好的做法是利用线段树,或者pr[i]标记离第i个数最近且有重复出现的数字的位置

下面是我自己的代码(因为我要用数组记录的原因进行了离散化)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

struct Node
{
int val,pos;
}temp[1000030],s[1000030];

bool cmp(Node p,Node q)
{
return p.val<q.val;
}

int vis[1000030],pr[1000030];

int main()
{
int n,m;
while (scanf("%d%d",&n,&m)!=EOF)
{
if (n==0 && m==0) break;
memset(vis,-1,sizeof(vis));
memset(pr,-1,sizeof(pr));
for (int i=0;i<n;i++)
{

scanf("%d",&temp[i].val);
temp[i].pos=i;
}
sort(temp,temp+n,cmp);

s[temp[0].pos].val=0;
s[temp[0].pos].pos=temp[0].val;
int tem=0;
for (int i=1;i<n;i++)
{
if (temp[i].val!=temp[i-1].val)
{
tem++;
s[temp[i].pos].val=tem;
s[temp[i].pos].pos=temp[i].val;

}
else
{
s[temp[i].pos].val=tem;
s[temp[i].pos].pos=temp[i].val;

}

}
//        for (int i=0;i<n;i++)
//        {
//            cout<<":"<<s[i].val<<endl;
//        }
for (int i=0;i<n;i++)
{
if (vis[s[i].val]!=-1)
{
pr[i]=vis[s[i].val];
vis[s[i].val]=i;
}
else
{
vis[s[i].val]=i;
}
}

for (int i=0;i<m;i++)
{
int l,r,flag=1;
scanf("%d%d",&l,&r);

for (int j=l-1;j<r;j++)
{
if (pr[j]>=l-1)
{
cout<<s[j].pos<<endl;
flag=0;
break;
}
}
if (flag==1) cout<<"OK"<<endl;
}
cout<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: