题目来源:P1540 [NOIP2010 提高组] 机器翻译 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题解:
一、方法:
用队列和一个判断数组
队列控制内存里存放的单词。
数组是为了方便查找队列里是否有需要找的单词,是否要去外存中去找。
题目要我们统计在外存中查找的次数,那我们就只要计算去判断去过外存的次数。
还要记得判断队列有没有满,如果满了要做额外的弹出队首操作。
二、过程
1.初始化
queue<int> que;
int dp[10005] = {0};
1)初始化一个数组并把所有的值赋值为0,(1代表队列(内存)中已存在单词,0则反之)
2)初始所有变量:
int m, n, x,fla=0,sum=0;
m为要查的单词数,
n为队列的容量,
x为要查找的单词,
fla代表此时队列的size,
sum表示进入外存的次数。
2.解决方案
因为每次只对一个单词进行判断,所以只需考虑:
1)若队列中已存在这个单词即 dp[x]==1 :
直接查询下个单词,因为题目没有让我们统计在内存中找单词的次数
2)若队列中不存在这个单词:
1、若队列已满且要查的单词x并不在队列中,把队首单词出队并赋值对应dp数组为0, 代表已不在队列(即队头出队了,内存中又空出了一个存单词的位置),然后再进行2操 作。
2、若队列未满,且x不在队列中,则先统计进入内存的次数(sum+1),然后把对应的dp数组赋值为1,即代表x入队单词存进了内存。
for (int i = 0; i < m;i++){
cin >> x;
if( dp[x]!=1){
if(fla==n){ //若队列已满,队头出队
dp[que.front()] = 0;
que.pop();
fla--;
}
sum++; //统计进入外存的次数
que.push(x); //把单词存入内存
dp[x] = 1;
fla++; //判断队列有没有满的变量
}
}
总之,dp数组是用来记录单词是否在队列中的,方便做到快速判断。
应为题目给的要求有:
- 所以申请了这么大数量的dp数组。
全代码:
int main(){
int m, n, x,fla=0,sum=0;
queue<int> que;
cin >> n>> m;
int dp[10005] = {0};
for (int i = 0; i < m;i++){
cin >> x;
if( dp[x]!=1){
if(fla==n){ //若队列已满,队头出队
dp[que.front()] = 0;
que.pop();
fla--;
}
sum++; //统计进入外存的次数
que.push(x); //把单词存入内存
dp[x] = 1;
fla++;
}
}
cout << sum;
return 0;
}
提交记录: