Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

郁闷了,自己测了好几组数据都是对的,但提交老是WA,达人们过来看看。程序附上了详细的注释。。。

Posted by yesrush at 2007-08-05 19:51:37 on Problem 3320
#include <stdio.h> 
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;

#define MAX  1000005
#define NMAX 1000005
long a[NMAX];//输入的数组
long chuli[NMAX];//将输入的数组a[]置入,进行排序
long youxu[NMAX];
//将排序好的chuli[],剔除重复的数字后,
//放入该数组,以后对某个数的查找,都依赖该数组
long tiao[NMAX];//tiao[i],第i位的数是否重复出现,若是,下次可跳过
long finded[NMAX];
//还未找到所有数字时使用,find[i]=1表示某个数在youxu[]数组中对应的下标为i时,找到了这个数
long chongfu[NMAX];//同一数字的最后一个所指的下标
long f[NMAX];//f[i],以第i个数为终点,最短符合条件的子串的长度

bool cmd(long a,long b)
{
	return a<b;
}
long find(long num,long da)
{	//在youxu[]数组中查找num所对应的下标,其中da是youxu[]数组的大小
	long low,high,mid;
	low=1;high=da;
	mid=(low+high)/2;
	while(low<high)
	{
		if(youxu[mid]==num) return mid;
		else if(youxu[mid]<num) low=mid+1;
		else high=mid-1;
		mid=(low+high)/2;
	}
	return mid;
}
long init(long num)
{
	long i,j;
	sort(chuli,chuli+num,cmd);
	youxu[1]=chuli[1];
	j=1;
	for(i=1;i<num;i++)
	{//将排好序的chuli[]数组中不重复的数放入youxu[]数组
		if(chuli[i]!=chuli[i+1]) youxu[++j]=chuli[i+1];
	}
	return j;//youxu[]的数组大小
}

void prlong(long num,long ci)
{	//这个子函数用来调试时打印tiao[],chongfu[],f[]的状态
	long i,j,k;
	cout<<ci<<endl;
	for(i=1;i<=num;i++) printf("%2d",i);
	cout<<endl;
	cout<<"this tiao"<<endl;
	for(i=1;i<=num;i++)
		printf("%2d",tiao[i]);
	cout<<"\nthis is chongfu"<<endl;
	for(j=1;j<=num;j++)
		printf("%2d",chongfu[j]);
	cout<<endl;
	cout<<"this is f"<<endl;
	for(k=1;k<=num;k++)
		printf("%2d",f[k]);
	cout<<endl;
}
long solve(long tnum)
{
	long first,flag,i,j,findnum=0,im,num,min;
	first=-1;//first为符合条件的子串最开始的位置
	flag=0;
	min=MAX;
	sort(chuli+1,chuli+1+tnum,cmd);
	num=init(tnum);//构造一个升序的非重复的序列
	memset(finded,0,sizeof(finded));
	memset(chongfu,0,sizeof(chongfu));
	memset(tiao,0,sizeof(tiao));
	memset(f,0,sizeof(f));
	for(i=1;i<=tnum;i++)
	{
		if(flag==0)
		{//还未有全部数字出现时
			if(findnum<num)
			{
				im=find(a[i],num);//找出a[i]在youxu[]数组中的下标,下同
				if(finded[im]==0)
				{//这个数字之前未出现
					findnum++;
					finded[im]=1;
				}
				else
				{//之前出现了
					tiao[chongfu[im]]=1;//原来的位置要置为跳过的标记
				}
				chongfu[im]=i;//该数字最后出现时的下标
				if(findnum==num) 
				{//全部数字刚好都出现了
					flag=1;
					f[i]=i;//从这里开始,以后的过程才能置f[]
					min=i;
					j=1;
					while(tiao[j]==1) j++;
					first=j;//找到最开始的子串的初始位置
				}
			}
		}
		else
		{//全部数字已经都出现了,也就是出现了题目中需要的子串
			if(a[i]==a[first])
			{	//如果新出现的数跟之前子串最开始的数一样
				tiao[first]=1;
				im=find(a[i],num);
				//first要一直往后跳到没有重复数字出现的地方
				first++;
				while(tiao[first]==1) first++;
				chongfu[im]=i;//这是该数最后出现的位置,其实也就是当前位置
			}
			else
			{//置之前出现的重复的数所对应的tiao
				im=find(a[i],num);
				tiao[chongfu[im]]=1;
				chongfu[im]=i;//这是该数最后出现的位置,其实也就是当前位置
			}
			f[i]=i-first+1;//子串长度
			if(f[i]<min) min=f[i]; 
		}
//		cout<<"first="<<first<<endl;
//		prlong(tnum,i);
	}
	return min;
}
int main()
{
	long tnum,i;
	scanf("%ld",&tnum);
	for(i=1;i<=tnum;i++) 
	{
		scanf("%ld",&a[i]);
		chuli[i]=a[i];
	}
	cout<<solve(tnum)<<endl;
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator