题的链接:P1540 机器翻译,点击这里!
注意:查找队列是否有该元素,用一个vis数组标记一下就好,不用太复杂去循环队列去找。。。
参考代码1.0: STL的queue + vis标记实现
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
#define MAX 20010
using namespace std;
int M, N, a, res;
bool vis[1010];
int main()
{
cin >> M >> N;
queue<int> q;
while(N--)
{
cin >> a;
if(vis[a]) continue;
vis[a] = true; res++;
if(q.size() >= M) vis[q.front()] = false, q.pop();
q.push(a);
}
cout << res << endl;
return 0;
}
参考代码2.0: 数组模拟,满了后将后面的都向前挪一位,缺点,挪动占用时间和内存太大。。。
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
#define MAX 20010
using namespace std;
int M, N, a, res,pos;
bool vis[1010];
int S[1010];
int main()
{
cin >> M >> N;
while(N--)
{
cin >> a;
if(vis[a]) continue;
vis[a] = true; res++;//m = 3
if(pos >= M)//0 1 2
{
vis[S[0]] = false;
for(int i = 1; i < M; i++) S[i - 1] = S[i];
pos--;
}
S[pos++] = a;
}
cout << res << endl;
return 0;
}
参考代码3.0: 2.0的优化版,少了数据的移动。元素满了直接将队首置为false并j++;
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
#define MAX 20010
using namespace std;
int M, N, a, res, pos, j;
bool vis[1010];
int S[1010];
int main()
{
cin >> M >> N;
while(N--)
{
cin >> a;
if(vis[a]) continue;
vis[a] = true; res++;//m = 3
if(pos >= M)//0 1 2
{
vis[S[j++]] = false;
// for(int i = 1; i < M; i++) S[i - 1] = S[i];
// pos--;
}
S[pos++] = a;
}
cout << res << endl;
return 0;
}
参考代码4.0: 也是2.0的优化版,少了数据的移动。用了L和R两个指针,自认为3.0更好。
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
#define MAX 20010
using namespace std;
int M, N, a, res, L, R;
bool vis[1010];
int S[1010];
int main()
{
cin >> M >> N;
while(N--)
{
cin >> a;
if(vis[a]) continue;
vis[a] = true; res++;//m = 3
if(R - L >= M)//0 1 2
{
vis[S[L]] = false;
L++;
}
S[R++] = a;
}
cout << res << endl;
return 0;
}