昨天晚上Coj1037这个题目调试了好久都没有出来答案。最开始我是用大根堆来维护书架上的书,记录编号为i的书下一次出现的位置为next[i],于是这样就把出现最晚的书最先拿出来,显然这是一个赤裸裸的贪心(裸贪),可是总是wa一组数据,诶,后来把我的程序发给殷牛,语音了近一个小时依然无果。
终于今天上午,殷牛给我发信息说他调出来了,还说错得很明显 诶,原来是continue语句前应该把更新next数组更新到b数组中间去哦。诶,太大意了,以后一定要多多注意,并且要养成良好的编程风格。
还有,收到殷牛的提醒,今天又学会了几招。
1.long long 数据类型的使用
2.读入和写出尽量用个scanf和printf,这样快得多
3.用的如果是stdio.h头文件 ,没有给定具体多少组数据时,要用 !=EOF 来判断所有数据是否读完,没有的话会出现输出格式不正确的情况,悲催。
下面我就把我用暴力方法做得Coj1037的程序贴到下面吧,殷牛说写得像屎一样 ,哈哈。
#i nclude <iostream>
using namespace std;
int pos[10003],next[10003],num[10003],a[103],flag[10003],b[103];
int main()
{
int t,i,j,k,l,n,m,s,ans;
cin>>t;
while (t--)
{
cin>>k>>n; ans=0;
for (i=0; i<10003; i++) pos[i]=next[i]=num[i]=flag[i]=-1;
for (i=0; i<=101; i++) b[i]=a[i]=0;
for (i=1; i<=n; i++)
{
cin>>num[i];
if (flag[num[i]] != -1 ) next[flag[num[i]]]=i;
flag[num[i]] = i;
}
for (i=1; i<=n; i++) if (next[i] == -1) next[i]=n+1;
//for (i=1; i<=n; i++ ) cout<<next[i]<<' '; cout<<endl;
s=1; ans=1; pos[num[1]]=1;
for (i=0; i<10003; i++) flag[i]=-1;
a[1]=num[1]; b[1]=next[1]; flag[num[1]]=1;
for (i=2; i<=n; i++)
{
if (flag[num[i]]==1)
{
j=pos[num[i]];
b[j]=next[b[j]];
continue;
}
ans++;
if (s<k)
{
s++; a[s]=num[i]; b[s]=next[i]; flag[num[i]]=1; pos[num[i]]=s;
}
else
{
l=1;
for (j=2; j<=s; j++) if (b[j]>b[l]) l=j;
flag[a[l]]=0;
a[l]=num[i]; b[l]=next[i];
flag[num[i]]=1; pos[num[i]]=l;
}
}
cout<<ans<<endl;
}
return 0;
}