1. 程式人生 > 其它 >P1047 [NOIP2005 普及組] 校門外的樹 題解

P1047 [NOIP2005 普及組] 校門外的樹 題解

技術標籤:ACM 演算法分析與設計演算法c++acm競賽c演算法陣列

文章目錄

思路

  考慮結合數學數軸上面的線段知識來解決,例如:

  • 輸入 #1

      500 3
      150 300
      100 200
      470 471
    
  • 作圖如下:
    數軸線段圖

程式碼

  • C++ 實現
// -*- coding: utf-8 -*-
//  @ Date   : 2020/5/20 13:14
//  @ Author : RichardLau_Cx
//  @ file   : Richard.cpp
//  @ IDE    : Dex-C++
//  @ Source : luogu

#include <iostream>
using namespace std; int main() { int l; // 馬路長度 int m; // 區域的數目 int index = 0; // 初始放至於0號索引 int add = 0; // 端點需要移除的樹 cin >> l >> m; int points[m+1][2]; // 存放m個區域的起始點座標,空出一行用來做交換 int remainder = l; // 剩餘的樹木數量 // while(m--) // { // 此方法不適合結合重合部分 // int u, v; // 一個區域的起始點和終止點的座標 // cin >> u >> v
// } for (int i=0; i < m; i++) { cin >> points[i][0] >> points[i][1]; /* if (points[i][0] > points[i][1]) { // 考慮到給定的起始位置可能為倒序,如:起始點位置 < 終止點位置時,把順序調整為升序, => 題目中已經表明:0 <= u <= v <= l int temp = points[i][0]; points[i][0] = points[i][1]; points[i][1] = temp; } */
} for (int i=0; i < m-1; i++) { // 處理思路:排序 + 判斷 for (int j=0; j < m-1; j++) { // cout << "here!" << endl; if (points[j][0] > points[j+1][0]) { // points[m][0], points[m][1] = points[j][0], points[j][1]; points[m][0] = points[j][0]; points[m][1] = points[j][1]; // points[j][0], points[j][1] = points[j+1][0], points[j+1][1]; points[j][0] = points[j+1][0]; points[j][1] = points[j+1][1]; // points[j+1][0], points[j+1][1] = points[m][0], points[m][1]; points[j+1][0] = points[m][0]; points[j+1][1] = points[m][1]; } } } /* cout << endl << endl << "begin: " << endl; for (int i=0; i < m; i++) { cout << points[i][0] << ' ' << points[i][1] << endl; } cout << "end: " << endl << endl << endl;; */ // for (int i=0; i < m; i++) // { // cout << points[i][0] << ' ' << points[i][1] << endl; // } for (int i=1; i < m; i++) { // cout << "here" << i << endl; if (points[index][1] >= points[i][0]) { if (points[index][1] < points[i][1]) { // 同時左邊的終止點小於右邊的終止點,擴大範圍 points[index][1] = points[i][1]; } // 證明發生了交集,重複和多餘區域置零 points[i][0]=0, points[i][1]=0; } else { // 未發生交集,索引後跳 index = i; add++; } } for (int i=0; i < m; i++) { remainder -= points[i][1] - points[i][0]; } // cout << "begin: " << endl; // for (int i=0; i < m; i++) // { // cout << points[i][0] << ' ' << points[i][1] << endl; // } // cout << "remainder: " << remainder-add << endl; cout << remainder-add << endl; return 0; } // TODO : 排序和左右資料調整存在問題,考慮優化排序方式 --- 現已優化