信息学奥赛一本通 1401:机器翻译 | 1859:【10NOIP提高组】机器翻译 | OpenJudge NOI 1.12 07 | 洛谷 P1540 [NOIP2010 提高组] 机器翻译

【题目链接】

ybt 1401:机器翻译
ybt 1859:【10NOIP提高组】机器翻译
OpenJudge NOI 1.12 07:机器翻译
洛谷 P1540 [NOIP2010 提高组] 机器翻译

【题目考点】

1. 模拟

2. 队列

3. 循环数组

一个长为n的循环数组下标范围为0~n-1,n-1的下一个位置是0。循环数组取下一个位置的方法为:
i = (i + 1) % n

【题解代码】

解法1:用循环数组模拟内存

用一个布尔数组记录某单词是否存在于内存内。
内存变量mem为循环数组,初值设为-1,如果其值大于等于0,说明已经保存单词。如果找到下一个位置后,发现这个位置已经存在单词,那么这里就是需要被覆盖的“最早进入内存的那个单词”将其覆盖。并将该单词设为“不存在于内存”。

#include
using namespace std;
bool hasWord[1005];//hasWord[i]:内存中是否有单词i 
int mem[105], mi;//mem[i]:内存中第i位置的单词 mi:内存中刚刚保存单词的位置 
int ct, m, n, word;//ct:计数 
int main()
{
	memset(mem, -1, sizeof(mem));//mem数组初值为-1,表示该位置没有保存单词。如果保存单词,值为非负整数。 
	cin >> m >> n;
	for(int i = 0; i < n; ++i)
	{
		cin >> word;
		if(hasWord[word] == false)//如果word单词不存在 
		{
			hasWord[word] = true;//将word单词设为已经存在 
			mi = (mi + 1) % m;//mi取循环数组中的下一个位置 
			if(mem[mi] >= 0)//如果这个内存中的新位置mi已经有值了 
				hasWord[mem[mi]] = false;//把mi位置保存的单词mem[mi]设为不存在 
			mem[mi] = word;//内存中新位置保存单词word 
			ct++;//这种情况需要到外存查字典 计数加1 
		}
	}
	cout << ct;
	return 0;
}

解法2:使用队列模拟

内存单词先进先出,符合队列的特点。可以用队列模拟。

#include
using namespace std;
bool hasWord[1005];//hasWord[i]:内存中是否有单词i 
queue<int> mem;//mem:内存 
int ct, m, n, word;//ct:计数 
int main()
{
	cin >> m >> n;
	for(int i = 1; i <= n; ++i)
	{
		cin >> word;
		if(hasWord[word] == false)//如果word单词不存在 
		{
			hasWord[word] = true;//将word单词设为已经存在 
			if(mem.size() == m)//如果已经存m个了
			{
				hasWord[mem.front()] = false;//队头单词设为不存在 
				mem.pop();//删除最早加入的单词 即队头出队
			} 
			mem.push(word);//内存中保存新单词word
			ct++;//这种情况需要到外存查字典 计数加1 
		}
	}
	cout << ct;
	return 0;
}

你可能感兴趣的:(信息学奥赛一本通题解,NOIP真题解答,洛谷题解,c++)