题面(from luogu)
(背景: 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。)
这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有,软件就会用它进行翻译;如果内存中没有,软件就会在外存中的词典内查找,查出单词的中文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译。
假设内存中有 M 个单元,每单元能存放一个单词和译义。每当软件将一个新单词存入内存前,如果当前内存中已存入的单词数不超过 M−1 ,软件会将新单词存入一个未使用的内存单元;若内存中已存入 M 个单词,软件会清空最早进入内存的那个单词,腾出单元来,存放新单词。
假设一篇英语文章的长度为 N 个单词。给定这篇待译文章,翻译软件需要去外存查找多少次词典?假设在翻译开始前,内存中没有任何单词。
输入格式:
共 2 行。每行中两个数之间用一个空格隔开。
第一行为两个正整数 M,N ,代表内存容量和文章的长度。
第二行为 N 个非负整数,按照文章的顺序,每个数(大小不超过 1000 )代表一个英文单词。文章中两个单词是同一个单词,当且仅当它们对应的非负整数相同。
输出格式:
一个整数,为软件需要查词典的次数。
样例.in
3 7
1 2 1 5 4 4 1
样例.out
5
说明:
每个测试点 1s
对于 10% 的数据有 N≤5,M=1 。
对于 100% 的数据有 0≤M≤100,0≤N≤1000 。
整个查字典过程如下:每行表示一个单词的翻译,冒号前为本次翻译后的内存状况:
空:内存初始状态为空。
1. 11 :查找单词1并调入内存。
2. 12 :查找单词 2 并调入内存。
3. 12 :在内存中找到单词 1 。
4. 125 :查找单词 5 并调入内存。
5. 254 :查找单词 4 并调入内存替代单词 1 。
6. 254 :在内存中找到单词 4 。
7. 541 :查找单词1并调入内存替代单词 2 。
共计查了 5 次词典。
题目分析
题目概述:给出一串数字,共计n个,你有一个长度最多为m的数字串,如果串中没有当前遇到的数字,需要添加,但如*果该串的长度在加上后大于m,则需要向前挤出位子,即是删去第一个,其他的向前移动一个单位,空出的给新的数字。(题目的样例说明说的很清楚)*
大家有没有发现,这题很像队列,先进,先出,所以我们便可以如此结合题目要求,进行模拟了
在对队列的维护中,我先是写了一个自己都不知道逻辑(瞎扯)的算法即如下:
t=f[d];
f[d]=p;
for(int i = d - 1; i >= 1; i--)
{
if (i % 2 == 0) //这个就很那什么了。。。额。。。
{
t1=f[i]; //两个变量螺旋交换(无视我在瞎扯)
f[i]=t;
}
else
{
t=f[i];
f[i]=t1;
}
这么去维护的话,自然要错了(AC WA WA WA AC WA AC WA WA WA),所以想出了这样的写法:
for(int i = 1; i <= d-1; i++)
f[i]=f[i+1]; //从前向后推
f[d]=p; //霸占挤出的位置
同上面那个额。。。(我也不想多说)好多了。。吧(勉强之笑)
代码
#include <bits/stdc++.h>
using namespace std;
int k[10009],f[10009],m,n,i,d=1,ans=1; //d的初值要是1,因为是从第一个开始找的,同样,ans也要是1,因为第一个数已经调用了
int find(int c) //判读是否需要维护
{
for(int i = 1; i <= d; i++)
if (c == f[i]) return 1; //找到了,直接return
return 0; //反之,需要进行维护
}
void get_more(int p)
{
int t=0,t1=0;
ans++; //进行统计
if (d < m) //如果队列没有超出其范围
{
d++; //向后拓展一个元素位置
f[d]=p; //置入
}
else
{
// t=f[d]; //恶心的大宝贝
// f[d]=p;
// for(int i = d - 1; i >= 1; i--)
// {
// if (i % 2 == 0)
// {
// t1=f[i];
// f[i]=t;
// }
// else
// {
// t=f[i];
// f[i]=t1;
// }
for(int i = 1; i <= d-1; i++)
f[i]=f[i+1]; //从前向后推
f[d]=p; //霸占挤出的位置
}
}
int main()
{
cin>>m>>n; //输入
for (int i = 1; i <= n; i++)
cin>>k[i];
f[1]=k[1]; //先取第一个
for (int i = 2; i <= n; i++) //开始处理队列
{
if (find(k[i]) == 0) get_more(k[i]); //判断是否需找
// if (d < m) d++; //之前的赘笔,之后再“get_more”函数中已经覆盖此功能了
// for (int i = 1; i <= d; i++)
//cout<<f[i]<<' ';
// cout<<endl;
}
// for (int i = 1; i <= m; i++)
// cout<<f[i];
cout<<ans; //输出
}
**蒟蒻新星c_uizrp_dzjopkl原创**