1. 程式人生 > 其它 >P6704 [COCI2010-2011#7] GITARA

P6704 [COCI2010-2011#7] GITARA

題目背景

Darko 有一個想象的外星朋友,他有十億根手指。外星人快速拿起吉他,在網上找到一段簡單的旋律並開始彈奏。

這個吉他像尋常一樣有六根弦,令其用 111 到 666 表示。每根弦被分成 PPP 段,令其用 111 到 PPP 表示。

旋律是一串的音調,每一個音調都是由按下特定的一根弦上的一段而產生的(如按第 444 弦第 888 段)。如果在一根弦上同時按在幾段上,產生的音調是段數最大的那一段所能產生的音調。

例:對於第 333 根弦,第 555 段已經被按,若你要彈出第 777 段對應音調,只需把按住第 777 段,而不需放開第 555 段,因為只有最後的一段才會影響該弦產生的音調(在這個例子中是第 777 段)。類似,如果現在你要彈出第 222 段對應音調,你必須把第 555 段和第 777 段都釋放。

請你編寫一個程式,計算外星人在彈出給定的旋律情況下,手指運動的最小次數。
題目描述

你有一個 6×P6 \times P6×P 的矩陣 AAA,初始狀態皆為 000。

對於所有要求 (i,j)(i,j)(i,j)

你需要滿足要求:

此時 Ai,jA_{i,j}Ai,j​ 狀態為 111。

對於 Ai,j+k(k>0)A_{i,j+k} (k>0)Ai,j+k​(k>0) 狀態為 000。

你在滿足要求的情況下需要求狀態轉換最小次數。
輸入格式

第一行包含兩個正整數 nnn ,PPP。它們分別指旋律中音調的數量及每根弦的段數。

下面的 nnn 行每行兩個正整數 iii ,jjj,分別表示能彈出對應音調的位置——弦號和段號,其為外星人彈奏的順序。

輸出格式

一個非負整數表示外星人手指運動次數最小值。
輸入輸出樣例
輸入 #1

5 15
2 8
2 10
2 12
2 10
2 5

輸出 #1

7

輸入 #2

7 15
1 5
2 3
2 5
2 7
2 4
1 5
1 3

輸出 #2

9

說明/提示
樣例 1 解釋

所有的音調都是由第二根弦產生的。首先按順序按 888 101010 121212 (count=3count=3count=3)。然後釋放第 121212 段(count=4count=4count=4)。最後,按下第 555 段,釋放第 888 101010 段 (count=7count=7count=7)。
樣例 2 解釋

對於每個操作,分別需要 111 111 111 111 333 000 222 次手指運動。

資料規模及約定

按下或釋放一段弦各計一次手指運動。彈弦不算手指的移動,而是一個彈吉他的動作。(指你不需要管他怎麼彈的,只需要按就是啦,說不定他可以用超能力呀)

對於 100%100%100% 的資料 n≤5×105n \le 5 \times 10^5n≤5×105 ,2≤P≤3×1052 \le P \le 3 \times 10^52≤P≤3×105
說明

本題滿分 707070 分。

譯自 COCI2010-2011 CONTEST #7 T3 GITARA

#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;

int main() {
    vector< stack<int> > a;
    int x,y;
    cin>>x>>y;
    int cao_zuo=0;
    for(int i=0;i<=6;i++){
        stack<int> linshi;
        linshi.push(-1);
        a.push_back(linshi);
    }
    for(int i=0;i<x;i++){
        int xian,duan;
        cin>>xian>>duan;
        if(a.at(xian).top()<duan &duan<=y){
            a.at(xian).push(duan);
            cao_zuo++;
        }else if(a.at(xian).top()>duan ){
            while (a.at(xian).top()>duan & a.at(xian).top()>-1){
                a.at(xian).pop();
                cao_zuo++;
            }
            if(a.at(xian).top()!=duan){
                a.at(xian).push(duan);
                cao_zuo++;
            }
        } else {

        }
    }
    cout<<cao_zuo<<endl;
    return 0;

}