1024 可怜的孩子

来源:互联网 发布:季琦和沈南鹏 知乎 编辑:程序博客网 时间:2024/04/29 08:37
 
描述

最近小赖的电脑遭遇了一次病毒的“洗礼”,所有的文件都已损坏。无奈之下,他只好求助于专业的数据恢复公司。工作人员在做完初步的检测后告诉小赖:只有一次恢复机会且只能恢复一段连续的文件。而每恢复一个文件则要花一个单位的钱。

小赖把他电脑里的文件分成了M类,他希望每类文件至少能恢复一个。但是小赖手上只有Money单位 的钱可供支配,所以他希望花的钱尽量的少。

输入

第一行有一个整数 T 表示数据的组数,对于每组数据:

第一行有三个整数 N, M, Money分别代表文件的总数(文件按存储顺序编号1~N), 文件的种类数,可供支配的钱数 (1≤N≤1,000,000 ,1≤M≤2000)。

第二行有N个整数,第i个整数代表编号为i的文件所属的分类(1~M中的一个)。

输出

对于每组测试数据,输出一行:

如果可以在Money单位的钱数内完成恢复,则输出两个整数,表示花钱最少的方案中恢复文件的起始位置和终止位置,即所要恢复的那段文件两端文件的编号a, b (a <b),如果有多种解决方案,则输出a最小的那组。

否则,输出“Poor child!”(不包括引号)。

样例输入
212 5 82 5 3 1 3 2 4 1 1 5 4 312 5 42 5 3 1 3 2 4 1 1 5 4 3
样例输出
2 7Poor child!

 

 

模拟题,恢复区域需要包含1到M,同时也要保证最长。

#include <iostream>#include <cstdlib>using namespace std;int main(){int number;cin>>number;int* index;int* zhi;int* result;while(number--){   int n,m,money;   cin>>n>>m>>money;   index=new int[m+1];   memset(index,0,sizeof(int)*(m+1));   zhi=new int[n+1];   result=new int[n+1];   for(int i=1;i<=n;i++)   {    cin>>zhi[i];   }   int k=0;int p;   for(int i=1;i<=n;i++)   {    if(index[zhi[i]]==0)    {     k++;     p=k;     index[zhi[i]]++;     if(k==m)     {      k=i;      break;     }    }    else    {     index[zhi[i]]++;    }      }   int k1 ;   for(int i=1;i<=k;i++)   {    if(index[zhi[i]]==1)    {     k1=i;     break;    }    else    {     index[zhi[i]]--;        }   }   result[k]=k1;   int mi=k-k1,s=k1,f=k;   for(int i=k+1;i<=n;i++)   {    index[zhi[i]]++;    for(int j=result[i-1];j<=i;j++)    {     if(index[zhi[j]]==1)     {      result[i]=j;      break;     }     else     {      index[zhi[j]]--;     }    }    if(i-result[i]<mi)    {     mi=i-result[i];     s=result[i];     f=i;    }   }   if(p<m)   cout<<"Poor child!"<<endl;   else if(mi+1>money)   cout<<"Poor child!"<<endl;   else   cout<<s<<" "<<f<<endl;   delete [] index;   delete [] zhi;   delete [] result;}return 0;}


 

原创粉丝点击