洛谷.P1540 [NOIP2010 提高组] 机器翻译之玩转队列

题目来源:P1540 [NOIP2010 提高组] 机器翻译 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题解:

洛谷.P1540 [NOIP2010 提高组] 机器翻译之玩转队列_第1张图片

一、方法:

用队列和一个判断数组

队列控制内存里存放的单词。

数组是为了方便查找队列里是否有需要找的单词,是否要去外存中去找。

题目要我们统计在外存中查找的次数,那我们就只要计算去判断去过外存的次数。

还要记得判断队列有没有满,如果满了要做额外的弹出队首操作。

 二、过程

1.初始化

queue que;
int dp[10005] = {0};

 1)初始化一个数组并把所有的值赋值为0,(1代表队列(内存)中已存在单词,0则反之)

 2)初始所有变量:

int m, n, x,fla=0,sum=0;

m为要查的单词数,

n为队列的容量,

x为要查找的单词,

fla代表此时队列的size,

sum表示进入外存的次数。

2.解决方案

因为每次只对一个单词进行判断,所以只需考虑:

1)若队列中已存在这个单词即 dp[x]==1 :

      直接查询下个单词,因为题目没有让我们统计在内存中找单词的次数

2)若队列中不存在这个单词:

     1、若队列已满且要查的单词x并不在队列中,把队首单词出队并赋值对应dp数组为0,            代表已不在队列(即队头出队了,内存中又空出了一个存单词的位置),然后再进行2操        作。

      2、若队列未满,且x不在队列中,则先统计进入内存的次数(sum+1),然后把对应的dp数组赋值为1,即代表x入队单词存进了内存。

for (int i = 0; i < m;i++){
        cin >> x;
        if( dp[x]!=1){
            if(fla==n){  //若队列已满,队头出队
                dp[que.front()] = 0;
                que.pop();
                fla--; 
        }
            sum++;    //统计进入外存的次数
            que.push(x);       //把单词存入内存
            dp[x] = 1;
            fla++;    //判断队列有没有满的变量
        
    }
}

总之,dp数组是用来记录单词是否在队列中的,方便做到快速判断。

应为题目给的要求有:

  • 洛谷.P1540 [NOIP2010 提高组] 机器翻译之玩转队列_第2张图片

  • 所以申请了这么大数量的dp数组。

 全代码:

int main(){
    int m, n, x,fla=0,sum=0;
    queue que;
    cin >> n>> m;
    int dp[10005] = {0};
    for (int i = 0; i < m;i++){
        cin >> x;
        if( dp[x]!=1){
            if(fla==n){  //若队列已满,队头出队
                dp[que.front()] = 0;
                que.pop();
                fla--; 
        }
            sum++;    //统计进入外存的次数
            que.push(x);       //把单词存入内存
            dp[x] = 1;
            fla++;
        
    }
}
    cout << sum;
    return 0;
}

 提交记录:

洛谷.P1540 [NOIP2010 提高组] 机器翻译之玩转队列_第3张图片

你可能感兴趣的:(机器翻译,人工智能,自然语言处理)