OJ提交地址:https://www.luogu.org/problemnew/show/P1540

http://noi.openjudge.cn/ch0112/07/

总时间限制: 1000ms 内存限制: 65536kB
描述

小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。

这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有,软件就会用它进行翻译;如果内存中没有,软件就会在外存中的词典内查找,查出单词的中文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译。

假设内存中有M个单元,每单元能存放一个单词和译义。每当软件将一个新单词存入内存前,如果当前内存中已存入的单词数不超过M−1,软件会将新单词存入一个未使用的内存单元;若内存中已存入M 个单词,软件会清空最早进入内存的那个单词,腾出单元来,存放新单词。

假设一篇英语文章的长度为N个单词。给定这篇待译文章,翻译软件需要去外存查找多少次词典?假设在翻译开始前,内存中没有任何单词。

输入
输入文件共2行。每行中两个数之间用一个空格隔开。
第一行为两个正整数M和N,代表内存容量和文章的长度。
第二行为N个非负整数,按照文章的顺序,每个数(大小不超过1000)代表一个英文单词。文章中两个单词是同一个单词,当且仅当它们对应的非负整数相同。

对于10%的数据有M = 1,N ≤ 5。
对于100%的数据有0 < M ≤ 100,0 < N ≤ 1000。

输出
共1行,包含一个整数,为软件需要查词典的次数。
样例输入
样例 #1:
3 7
1 2 1 5 4 4 1 样例 #2:
2 10
8 824 11 78 11 78 11 78 8 264
样例输出
样例 #1:
5 样例 #2:
6
提示
输入输出样例 1 说明:

整个查字典过程如下:每行表示一个单词的翻译,冒号前为本次翻译后的内存状况:

空:内存初始状态为空。
1. 1:查找单词1并调入内存。
2. 1 2:查找单词2并调入内存。
3. 1 2:在内存中找到单词1。 
4. 1 2 5:查找单词5并调入内存。
5. 2 5 4:查找单词4并调入内存替代单词1。
6. 2 5 4:在内存中找到单词4。
7. 5 4 1:查找单词1并调入内存替代单词2。

共计查了5 次词典。

算法分析:

用队列先进先出的特性模拟内存存放单词;用一个一维数组标记某一个单词是否在于内存中以便快速确定是否需要查找词典。其余的基本就是纯粹模拟了。

有一点需要注意:若是使用循环队列,需要好好检查循环队列中元素个数的计算是否正确。

代码一:不使用循环队列,直接把队列定义得足够大

 #include<stdio.h>
#define maxQueueLength 1005
int main()
{
int M,N;
int que[maxQueueLength]={},check[]={}; // que[]是循环队列,用来模拟内存;check[i]==1表示i在内存中。
int ans=,begin,end,i,t;
scanf("%d%d",&M,&N); begin=end=;//初始化队列
for(i=;i<N;i++)
{
scanf("%d",&t);
if(check[t]==)//查找内存,发现内存中没有t存在
{
ans++;//查找字典的次数增加一次
//现在开始做单词放进内存的过程
if(end-begin<M)
{
que[end++]=t;
}
else //end-begin>=M
{
check[que[begin]]=;
begin++;
que[end++]=t;
}
check[t]=;//标记t已经在内存中
}
}
printf("%d\n",ans);
return ;
}

代码二:使用循环队列,节省一些队列空间

 #include<stdio.h>
#define maxQueueLength 105
int main()
{
int M,N;
int que[maxQueueLength]={},check[]={}; // que[]是循环队列,用来模拟内存;check[i]==1表示i在内存中。
int ans=,begin,end,i,t,count; scanf("%d%d",&M,&N); begin=end=;//初始化队列
for(i=;i<N;i++)
{
scanf("%d",&t);
if(check[t]==)//查找内存,发现内存中没有t存在
{
ans++;//查找字典的次数增加一次
//现在开始做单词放进内存的过程
if(end>=begin) count=end-begin;
else count=maxQueueLength-begin+end; if(count<M)
{
que[end++]=t;
if(end>=maxQueueLength) end=end%maxQueueLength;
}
else //end-begin>=M
{
check[que[begin]]=;
begin++;
que[end++]=t;
if(begin>=maxQueueLength)begin=begin%maxQueueLength;
if(end>=maxQueueLength)end=end%maxQueueLength;
}
check[t]=;//标记t已经在内存中
}
}
printf("%d\n",ans);
return ;
}

下面的代码也是用了循环队列,不过代码的可读性可能好一些哈哈哈

 #include <stdio.h>
#include <stdlib.h> int main()
{
int m,n;
int i;
int a[]={},count=;//a[]表示内存的空间。count记录当前内存中已经存有的单词个数
int firstIn=,lastIn=;//firstIn表示最早进入内存的单词在内存中的下标。lastIn表示下一个可以用于存储新单词的空闲空间的下标。
int b[]={};//b[i]==1表示i这个单词在内存中。否则表示i不在内存中。
int ans=,t; scanf("%d%d",&m,&n);
for(i=;i<n;i++)
{
scanf("%d",&t);//依次输入n个单词
if(b[t]==)//若单词t不在内存中
{
ans++;//需要查一次字典 //查完字典后需要把刚查的单词存入内存
if(count<m)//内存空间还有空闲
{
a[lastIn]=t;
b[t]=;
count++;
lastIn++;
lastIn=lastIn%m;
}
else//内存空间已经满了
{
//先腾空一个位置
b[a[firstIn]]=;
//a[firstIn]=0;
firstIn++;
firstIn=firstIn%m; //然后再把新单词放入内存
a[lastIn]=t;
b[t]=;
lastIn++;
lastIn=lastIn%m;
}
}
}
printf("%d\n",ans);
return ;
}

NOIP2010提高组 机器翻译的更多相关文章

  1. NOIP2010提高组 机器翻译 -SilverN

    /**/ #include<iostream> #include<cstdio> #include<cmath> #include<cstring> # ...

  2. [NOIP2010 提高组] 机器翻译

    问题描述 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换.对于每个英文单词,软件会先在内存中查 ...

  3. noip2010提高组题解

    NOIP2010提高组题解 T1:机器翻译 题目大意:顺序输入n个数,有一个队列容量为m,遇到未出现元素入队,求入队次数. AC做法:直接开1000的队列模拟过程. T2:乌龟棋 题目大意:有长度为n ...

  4. NOIP2010提高组真题部分整理(没有关押罪犯)

    目录 \(NOIP2010\)提高组真题部分整理 \(T1\)机器翻译: 题目背景: 题目描述: 输入输出格式: 输入输出样例: 说明: 题解: 代码: \(T2\)乌龟棋 题目背景: 题目描述: 输 ...

  5. NOIP2010提高组乌龟棋 -SilverN

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  6. 洛谷 P1541 乌龟棋 & [NOIP2010提高组](dp)

    传送门 解题思路 一道裸的dp. 用dp[i][j][k][kk]表示用i个1步,j个2步,k个3步,kk个4步所获得的最大价值,然后状态转移方程就要分情况讨论了(详见代码) 然后就是一开始统计一下几 ...

  7. 洛谷 P1525 关押罪犯 & [NOIP2010提高组](贪心,种类并查集)

    传送门 解题思路 很显然,为了让最大值最小,肯定就是从大到小枚举,让他们分在两个监狱中,第一个不符合的就是答案. 怎样判断是否在一个监狱中呢? 很显然,就是用种类并查集. 种类并查集的讲解——团伙(很 ...

  8. NOIP2010提高组 关押罪犯 -SilverN

    (洛谷P1525) 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”( ...

  9. [NOIP2010] 提高组 洛谷P1525 关押罪犯

    刚才做并查集想到了这道以前做的题,干脆一并放上来 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可 ...

随机推荐

  1. POJ 1094 Sorting It All Out 【拓扑排序】

    <题目链接> 题目大意: 对于N个大写字母,给定它们的一些关系,要求判断出经过多少个关系之后可以确定它们的排序或者排序存在冲突,或者所有的偏序关系用上之后依旧无法确定唯一的排序. 解题分析 ...

  2. 满血复活--来自世一大的WAR

    最需要复习的清单 1.二分 2.图论 3.数论 4.dp

  3. linux 学习笔记 cpio命令

    1 文件或目录打包 打包有如下多种情况 A>包含子目录打包 find /usr/lib -print /cpio -o >/uo/temp1.cpio 将/usr/lib目录下的文件与子目 ...

  4. BZOJ.2000.[HNOI2010]stone取石头游戏(博弈)

    BZOJ 洛谷 低估这道神题了_(:з」∠)_ MilkyWay好狠啊(小声) \(Description\) 有一些数字,被分成若干双端队列(从两边都可以取)和最多两个栈(只能从某一边一个一个取)的 ...

  5. js点击回到顶部2

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>点 ...

  6. HTTP 500 Invalid bound statement错误

    整合SSM框架的时候出现的错误,根据提示信息,找不到 dao.IUserDao.insertUser 方法,可能是mybatis的配置文件出现了问题. 在网上查了一些解决办法,说的最多的是mapper ...

  7. 2017-2018 ACM-ICPC Southeast Regional Contest (Div. 1)

    A. Ducks in a Row 当$n\times k>|S|$时,显然无解. 否则最优解中翻转的区间一定两两不相交,设$f[i][j][x][y]$表示考虑前$i$个位置,第$i$个位置翻 ...

  8. Exception引起的性能问题

    先show一下两段代码,两段代码都能比较好的实现业务逻辑,但是在高并发下,如果传入的参数为空,那么两段代码的性能表现完全不一样. private static string Get(string fi ...

  9. Java 始终要覆盖toString

    java.lang.Object提供了toString方法的一个实现,它包含类的名称,以及一个“@”符号,接着是散列码的无符号十六进制表示法,例如“PhoneNumber@163b91”.在实际应用中 ...

  10. jquery 获取奇数索引的元素,获取复选框,判断是否选中

    $(".btn-xs:odd").click(function(){ var $buy_num=$(this).prev("#buy_num").val(); ...