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. NN:神经网络算法进阶优化法,进一步提高手写数字识别的准确率—Jason niu

    上一篇文章,比较了三种算法实现对手写数字识别,其中,SVM和神经网络算法表现非常好准确率都在90%以上,本文章进一步探讨对神经网络算法优化,进一步提高准确率,通过测试发现,准确率提高了很多. 首先,改 ...

  2. URAL 1099 Work Scheduling (一般图最大匹配) 模板题【带花树】

    <题目链接> <转载于 >>>  > 题目大意: 给出n个士兵,再给出多组士兵之间两两可以匹配的关系.已知某个士兵最多只能与一个士兵匹配.求最多能够有多少对匹 ...

  3. HYSBZ 4034 【树链剖分】+【线段树 】

    <题目链接> 题目大意: 有一棵点数为 N 的树,以点 1 为根,且树点有权值.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...

  4. mysql 数据库(二)数据库的基本操作

    mysql 数据库(二)数据库的基本操作 用户管理,添加权限,创建,显示,使用数据库 1 显示数据库:show databases; 默认数据库: mysql - 用户权限相关数据 test - 用于 ...

  5. Is there a TRY CATCH command in Bash

    Is there a TRY CATCH command in Bash? No. Bash doesn't have as many luxuries as one can find in many ...

  6. Asp.Net判断文件是否存在

    在上传文件时经常要判断文件夹是否存在,如果存在就上传文件,否则新建文件夹再上传文件 判断语句为 if (System.IO.Directory.Exists(Server.MapPath(" ...

  7. 【开源GPS追踪】 之 硬件开源

    根据设定目标: 使用GPS 采集经纬度,然后通过GPRS模块/wifi 发送到服务器显示,WIFI不常有,所有就使用GPRS模块! 对于GPS模块,没有特殊要求,只要输出格式符合NMEA协议即可,为了 ...

  8. yum与rpm的区别以及详细介绍

    rpm是由红帽公司开发的软件包管理方式,使用rpm我们可以方便的进行软件的安装.查询.卸载.升级等工作.但是rpm软件包之间的依赖性问题往往会很繁琐,尤其是软件由多个rpm包组成时. Yum(全称为 ...

  9. Python3从零开始爬取今日头条的新闻【三、滚动到底自动加载】

    Python3从零开始爬取今日头条的新闻[一.开发环境搭建] Python3从零开始爬取今日头条的新闻[二.首页热点新闻抓取] Python3从零开始爬取今日头条的新闻[三.滚动到底自动加载] Pyt ...

  10. (转)JavaWeb学习之Servlet(一)----MyEclipse及Tomcat的配置

    [声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4134921.html [开发环境] 物理机版本:Win 7旗舰版(64位 ...