这道ACM题我实在是不会了。。。(POJ3320)求大神

PainPain0 2012-03-02 05:17:42



题意大概是在一串连续的数字中找到包含所有出现过的数字的最小连续段。

我写了个用哈希表的实现方式。。然后维护start和end的值。。


#include <iostream>
#include"stdio.h"
#include"algorithm"

#define PRIME 65536
#define Max 1000000
using namespace std;

int p;
int q[Max];
int T[Max];

struct node{
int v,next,num;

}Hash[PRIME*2];

int hashl;

bool cmp(int a,int b){return a<b;}

bool deleteh(int a){//删除,true 表示删除光了 a ;false 表示还有a 在队列里。

int h=a%PRIME;

while(Hash[h].next!=-1){
if(Hash[h].v==a){
if(Hash[h].num){
//cout<<"error del."<<endl;
Hash[h].num--;
}

if(!Hash[h].num){

return true;
}
return false;
}

h=Hash[h].next;
}
return true;

}

bool inserth(int a){//插入,true表示以前队列里没有a
int h=a%PRIME;
if(Hash[h].next==-1){
//insert
Hash[h].num=1;
Hash[h].next=hashl;
Hash[hashl].next=-1;
Hash[h].v=a;
hashl++;
return true;
}
else {
int u=h;

while(Hash[u].v!=a&&Hash[u].next!=-1){
u=Hash[u].next;
}

if(Hash[u].v!=a){
Hash[u].next=hashl;
Hash[u].v=a;
Hash[++hashl].next=-1;
return true;
}
else{
Hash[u].num++;

if(Hash[u].num>1){return false;}
else {return true;}
}
}
}

void findh(int a){//没用
int h=a%PRIME;

while(Hash[h].next!=-1&&Hash[h].v!=a){h=Hash[h].next;}
if(Hash[h].v==a&&Hash[h].num>0){puts("Found it.");}
else {puts("Not found.");}

}

int main()
{
int j;
freopen("input","r",stdin);

while(scanf("%d",&p)!=EOF){
int i;
if(!p){cout<<"0"<<endl;continue;}

for(j=0;j<PRIME*2;j++){
Hash[j].next=-1;
Hash[j].num=0;
Hash[j].v=-1;

}
hashl=PRIME;

for(i=0;i<p;i++){
scanf("%d",&q[i]);
T[i]=q[i];
}

sort(T,T+p,cmp);
int tot_sum=1;

for(i=1;i<p;i++){
if(T[i]!=T[i-1]){tot_sum++;}
}

//filter
if(tot_sum<=1){cout<<tot_sum<<endl;continue;}

int count_n=1,start=0,end=1;
int min_len=p+1;

inserth(q[0]);

while(end!=p){


if(inserth(q[end])){count_n++;}//新出现了一个数,count就++

while(start<end&&count_n==tot_sum){//等于总数时更新一下最小值
//jud count_n
if(end-start+1<min_len){min_len=end-start+1;}

if(deleteh(q[start])){count_n--;}//成功删光了 一个元素,count--;

start++;

}

end++;

//printf("start:%d end:%d count:%d\n",start,end,count_n);

}
//if(count_n==tot_sum){cout<<"!!!error"<<endl;break;}

cout<<min_len<<endl;

}
return 0;
}

...全文
123 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧