题解补充信息:
- 算法1的代码不能完全AC,30分(在相关位置补入提醒)
我们先看一下题目:
题目描述
这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有,软件就会用它进行翻译;如果内存中没有,软件就会在外存中的词典内查找,查出单词的中文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译。
假设内存中有 M M M 个单元,每单元能存放一个单词和译义。每当软件将一个新单词存入内存前,如果当前内存中已存入的单词数不超过 M − 1 M-1 M−1,软件会将新单词存入一个未使用的内存单元;若内存中已存入 M M M 个单词,软件会清空最早进入内存的那个单词,腾出单元来,存放新单词。
假设一篇英语文章的长度为 N N N 个单词。给定这篇待译文章,翻译软件需要去外存查找多少次词典?假设在翻译开始前,内存中没有任何单词。
好复杂呀,这让我怎么做?!不急,只要分几步。
算法1:队列
答题第一步:提取信息
根据题目的信息及数据范围(1≤M≤100,1≤N≤1000)可知:本题考查的是模拟(“内存”插入删除)以及队列 (虽然我是用数组)
答题第二步:构建思路
仔细阅读题目描述,先用人脑进行模拟,例如:
n=5,m=2
输入:1 2 3 2 3
step1:读取到1,不在内存中
内存:1
step2:读取到2,不在内存中
内存:1 2
step3:读取到3,不在内存中(内存已满)
模拟到step3时的情况:内存没有剩余空间(AC关键)
继续:
step3:读取到3,不在内存中(内存已满)
内存操作:
1.内存空间不足,释放1
2.1被释放后的空位存入3(注意:这个位置应在最后,即最后插入)
内存:2 3
step4:读取到2,在内存中
step5:读取到3,在内存中
程序结束,输出3
答题第三步:组建代码
回顾一下模拟过程,一步步构建代码。
根据模拟过程发现,“内存”的操作方式是先进先出,符合队列标准,所以先定义一个队列:
queue<int> memory;
读取到不存在内存中的数据时,先进行查找(for循环队列)
for(int i=1;i<=memory.size();i++)
{
if(memory.front()==x)//x是“单词”
{
found=true;//标记已找到
break;
}
memory.push(memory.front());
memory.pop();//队列循环
}
接下来加上一个判断,确定是否找到(found派上用场啦!)
if(!found)//没有找到
{
if(memory.size()==m)//内存已满
{
memory.pop();//删除
memory.push(st);
}
else
memory.push(st);
ans++;
}
最后输出就行啦!
代码:
#include<bits/stdc++.h>
using namespace std;
int m,n;
int st;
int ans=0;
bool found=false;
queue<int> memory;
int main()
{
cin>>m>>n;
for(int i=1;i<=n;i++)
{
cin>>st;//在线处理
found=false;
for(int j=1;j<=memory.size();j++)
{
if(memory.front()==st)
{
found=true;
break;
}
memory.push(memory.front());
memory.pop();
}
if(!found)
{
if(memory.size()==m)
{
memory.pop();
memory.push(st);
}
else
memory.push(st);
ans++;
}
}
cout<<ans;
}
注意,本代码并不能AC,30分,无法判断0是一个单词的数据(#2数据WA,本提醒详见洛谷@juju的题解,附上原文链接
算法2:数组模拟
这没什么好讲的,把算法1改一下就行。
直接贴代码:
#include<bits/stdc++.h>
using namespace std;
int m,n;
int st;
int memory[101];//“内存”
int _size=0;//当前内存内元素数量
int ans=0;
bool found=false;
void move()//删除后移动元素,复杂度为O(n-1)不超时
{
for(int i=2;i<=m;i++)
swap(memory[i],memory[i-1]);
}
int main()
{
cin>>m>>n;
memset(memory,-1,sizeof(memory));//统一初始化
for(int i=1;i<=n;i++)
{
cin>>st;
found=false;
for(int j=1;j<=_size;j++)//查找
{
if(memory[j]==st)
{
found=true;
break;
}
}
if(!found)
{
if(_size==m)//内存已满
{
memory[1]=-1;//删除
move();//移动
memory[_size]=st;//添加新元素
}
else
memory[++_size]=st;//添加新元素
ans++;
}
}
cout<<ans;//输出
}