Shortest Subsequence
Time Limit: 1000ms
Memory Limit: 65536kb
Description
Logicalmars has a friend who is very superstitious. He thinks randomly written sequence is not that "random", which he explains that you write them according to your sub-consciousness. He kept writing random numbers day and day and he thinks random numbers should have a limitation, let us say m, which means all numbers other than 1~m are noise that shouldn't be considered. 

Now, with a lot of random numbers in hand (n in total), he wants to recognize some subsequence, which should consist of numbers from 1 to m at least once each and could contain some noise. He wants the shortest one, so he turns to you for your help.

Input
The input consists of several test cases. 

In each test case, first line contains m, n, as described above. Then comes a line with n integers. These numbers are indexed from 1 to n. A pair of m=0 and n=0 indicates the end the input.

1<=m<=5000, 0<=n<=10^6, using 32-bit integer is enough for numbers.

Output
For each test case, output the minimum length of the subsequence containing every number from 1 to m, and the index of the rightmost number of the subsequence. If multiple solutions exist, output the leftmost solution.

Output -1 if the subsequence doesn't exist.

Sample Input
4 10
1 0 0 2 2 3 4 2 1 0
4 10
0 0 0 0 1 2 3 0 0 0 
0 0
Sample Output
4 9
-1
这题我是用队列模拟的,有点难解释思路,虽然时间空间上不是最优的,但一次AC了有点惊喜
#include <stdio.h>
#include <iostream>
using namespace std;
struct fs
{
    int num;
    int pot;
}que[1000006];
int main()
{
    int num[5007]={0};
    int n,m;
    while (scanf("%d%d",&m,&n)!=EOF)
    {
        int f,i,j,l,front,left=0,sum,max=0,r,temp,q;
        if (m==0&&n==0)break;
        for (i=0;i<=5007;i++)
            num[i]=0;
        r=1;
        for (i=1;i<=n;i++)
        {
            scanf("%d",&f);
            if (f>=1&&f<=m)
            {
                que[r].num=f;
                que[r++].pot=i;
            }
        }
        q=1;
        for (i=1;i<r;i++)
        {
            l=1;
            f=que[i].num;
            num[f]++;
            for (j=1;j<=m;j++)
                if (num[j]==0)
                {
                    l=0;
                    break;
                }
            if (l==1)
            {
                q=0;
                max=i;
                break;
            }
        }
        front=1;
        sum=que[max].pot-que[front].pot+1;
        left=que[max].pot;
        for (i=max+1;i<r;i++)
        {
            f=que[i].num;
            num[f]++;
            while (num[que[front].num]>1)
            {
                num[que[front].num]--;
                front++;
            }
            temp=que[i].pot-que[front].pot+1;
            if (temp<sum)
            {
                sum=temp;
                left=que[i].pot;
            }
        }
        if (q==1) printf("-1\n");
        else printf("%d %d\n",sum,left);
    }
    return 0;
}