【NOIP2010提高组t1】机器翻译

题目描述:

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

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

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

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

输入格式:

输入文件共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 次词典。

本题也可以用双端队列。

经典模拟题,再搭配STL容器求解

代码实现:
#include<bits/stdc++.h>
using namespace std;
deque<int>q;
int m,n,k,cnt;
int main(){
	cin>>m>>n;
	for(int i=1;i<=n;i++){
		cin>>k;
		bool flag=true;
		for(int j=0;j<m;j++){
			if(q[j]==k){
				flag=false;
				break;
			}
		}
		if(flag){
			cnt++;
			if(q.size()<m){
				q.push_front(k);
			}
			else{
				q.pop_back();
				q.push_front(k);
			}
		}
	}
	cout<<cnt;
	return 0;
}

这样能过WZOI了,但是想过洛谷等平台还差点。

in:
100 500	
363 91 14 37 668 668 210 285 436 436 37 91 91 363 627 652 735 210 989 585 331 735 819 285 624 0 652 331 749 652 0 469 709 285 860 9 725 37 54 363 0 45 747 155 652 14 37 937 293 21 819 629 117 668 293 37 99 363 761 627 438 177 285 749 440 121 217 517 989 280 273 45 754 725 721 438 659 273 37 436 206 700 155 890 210 14 217 487 24 29 934 21 41 341 761 24 819 158 484 482 550 652 243 541 668 210 190 969 159 747 271 731 929 31 293 175 285 131 969 512 183 440 341 271 462 735 421 697 38 31 373 599 630 787 794 818 177 725 961 308 805 14 9 913 70 415 489 140 1 357 240 517 49 438 469 177 243 827 987 619 308 159 487 789 735 438 177 104 934 759 530 471 541 271 913 787 621 158 759 593 440 875 271 24 175 535 668 217 543 388 176 397 716 308 930 514 627 183 54 913 436 761 241 929 190 31 619 210 423 629 1 495 440 530 183 818 875 805 570 363 104 121 731 747 395 262 104 99 419 14 535 541 913 341 287 127 390 104 832 260 698 989 934 885 41 721 934 619 240 260 935 553 857 251 512 31 619 465 177 91 697 13 519 21 546 550 546 987 827 887 196 585 961 827 593 121 435 655 401 217 214 536 131 85 735 38 91 158 975 471 91 469 716 418 734 850 805 397 13 167 255 619 697 175 495 241 285 471 575 734 763 45 107 702 219 137 348 571 243 21 93 827 328 163 932 285 550 348 931 394 24 372 570 828 512 747 299 857 159 448 41 469 512 131 550 497 482 998 438 49 220 512 585 323 619 186 619 372 534 497 543 594 536 289 312 987 886 415 575 627 979 536 140 481 373 832 172 103 436 803 159 772 819 591 137 550 131 312 175 183 327 45 438 435 979 14 763 176 827 29 372 619 325 937 113 341 519 417 293 714 260 841 170 357 790 517 418 789 386 768 321 704 435 593 0 880 969 723 739 130 372 903 305 229 397 798 739 381 219 704 381 745 13 782 29 974 305 542 513 448 889 944 111 986 754 320 362 957 381 158 608 961 128 600 159 783 394 766 438 373 117 65 819 693 363 612 451 693 937 591 610 283 511 177 127 841 998 825 435 553 229 935 943 283 376 688 397 630 770 918
ans:
297

输入这个数据你会发现输出结果不一致。

这是改良版,运用布尔类型数组vis标记:

#include<bits/stdc++.h>
using namespace std;
deque<int>q;
int m,n,k,cnt;
bool vis[10001];
int main(){
	cin>>m>>n;
	for(int i=1;i<=n;i++){
		cin>>k;
		if(vis[k])continue;
		cnt++;
		if(q.size()<m){
			q.push_front(k);
		}
		else{
			vis[q.back()]=0;
			q.pop_back();
			q.push_front(k);
		}
		vis[k]=1;
	}
	cout<<cnt;
	return 0;
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值