<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一舉拿下貪心

          共 19301字,需瀏覽 39分鐘

           ·

          2021-05-14 03:56

          大家好,我是Simon郎,一個每天想要博學一點點的小青年!

          今天為大家分享的是貪心算法

          貪心算法:貪心算法(又稱貪婪算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優(yōu)上加以考慮,算法得到的是在某種意義上的局部最優(yōu)解,從而使得得到的最終結果是全局最優(yōu)或者接近于全局最優(yōu)。

          本文選取LeetCode比較有代表性的題目來學習貪心算法,選取的題目如下:

          • 1、分發(fā)餅干(455)

          • 2、分發(fā)糖果(135)

          • 3、無重疊區(qū)間(435)

          • 4、種花問題(605)

          • 5、用最少數(shù)量的箭引爆氣球(452)

          • 6、劃分字母區(qū)間(763)

          • 7、買賣股票的最佳時機(122)

          • 8、根據(jù)身高重建隊列(406)

          • 9、非遞減數(shù)列(665)

          每道題目都有五部分組成:

          • 題目描述
          • 示例
          • 解題思路
          • 代碼實現(xiàn)
          • 執(zhí)行結果

          1、分發(fā)餅干(455)

          題目描述

          假設你是一位很棒的家長,想要給你的孩子們一些小餅干。但是,每個孩子最多只能給一塊餅干。

          對每個孩子 i,都有一個胃口值 g[i],這是能讓孩子們滿足胃口的餅干的最小尺寸;并且每塊餅干 j,都有一個尺寸 s[j] 。如果 s[j] >= g[i],我們可以將這個餅干 j 分配給孩子 i ,這個孩子會得到滿足。你的目標是盡可能滿足越多數(shù)量的孩子,并輸出這個最大數(shù)值。

          示例:

          示例1:

          輸入: g = [1,2,3], s = [1,1] 

          輸出: 1 

          解釋: 你有三個孩子和兩塊小餅干,3個孩子的胃口值分別是:1,2,3。雖然你有兩塊小餅干,由于他們的尺寸都是1,你只能讓胃口值是1的孩子滿足。所以你應該輸出1

          示例2:

          輸入: g = [1,2], s = [1,2,3] 

          輸出: 2 

          解釋: 你有兩個孩子和三塊小餅干,2個孩子的胃口值分別是1,2。你擁有的餅干數(shù)量和尺寸都足以讓所有孩子滿足。所以你應該輸出2.

          思路:

          采用貪心算法:大尺寸的餅干能夠滿足胃口小的孩子,也能夠滿足胃口大的孩子,所以對于大尺寸的餅干要優(yōu)先滿足胃口大的孩子,而胃口小的孩子用小尺寸的餅干來喂,盡量減少浪費。

          局部最優(yōu):充分利用餅干尺寸滿足一個;全局最優(yōu):就是滿足盡可能多的孩子

          首先將餅干數(shù)組和孩子數(shù)組進行排序,然后從前往后依次進行比較。

          胃口比餅干尺寸小,孩子被滿足,繼續(xù)遍歷下一個孩子和下一塊餅干; 胃口比餅干尺寸大,遍歷下一塊餅干。

          代碼:

          class Solution {
              public int findContentChildren(int[] g, int[] s) {
                  Arrays.sort(g);
                  Arrays.sort(s);
                  int child=0, cookie=0;
                  while(child<g.length && cookie<s.length){
                      if(g[child]<=s[cookie]) child++;
                      cookie++;
                  }
               return child;
              }
          }

          執(zhí)行結果:

          分發(fā)餅干

          2、分發(fā)糖果(135)

          題目描述

          老師想給孩子們分發(fā)糖果,有 N 個孩子站成了一條直線,老師會根據(jù)每個孩子的表現(xiàn),預先給他們評分。要按照以下要求,幫助老師給這些孩子分發(fā)糖果:每個孩子至少分配到 1 個糖果。評分更高的孩子必須比他兩側的鄰位孩子獲得更多的糖果。

          那么這樣下來,老師至少需要準備多少顆糖果呢?

          示例

          示例 1:

          輸入:[1,0,2] 

          輸出:5 

          解釋:你可以分別給這三個孩子分發(fā) 2、1、2 顆糖果。

          示例 2:

          輸入:[1,2,2] 

          輸出:4 

          解釋:你可以分別給這三個孩子分發(fā) 1、2、1 顆糖果。第三個孩子只得到 1 顆糖果,這已滿足上述兩個條件。

          解題思路:

          相鄰孩子,評分高的孩子必須獲得更多的糖果,因此拆分成兩個規(guī)則:

          • 規(guī)則定義:設學生A和學生B左右相鄰,A在B的左邊

          左規(guī)則:當B>A時,B的糖果比A的數(shù)量多

          右規(guī)則:當A>B時,則A的糖果比B的糖果數(shù)量多

          相鄰的學生中,評分高的學生必須獲得更多的糖果 等價于 所有學生滿足左規(guī)則且滿足右規(guī)則。

          • 算法流程
          • 把所有孩子的糖果數(shù)初始化為 1。
          • 先從左往右遍歷一遍,如果右邊孩子的評分比左邊的高,則右邊孩子的糖果數(shù)更新為左邊孩子的 糖果數(shù)加 1。
          • 再從右往左遍歷一遍,如果左邊孩子的評分比右邊的高,且左邊孩子當前的糖果數(shù) 不大于右邊孩子的糖果數(shù),則左邊孩子的糖果數(shù)更新為右邊孩子的糖果數(shù)加 1。

          代碼:

          class Solution {
              public int candy(int[] ratings) {
                  //循環(huán)遍歷兩次
                  int[] candy=new int[ratings.length];
                  int count=candy.length;
                  for(int i=1;i<ratings.length;i++){
                      if(ratings[i-1]<ratings[i]){
                          candy[i]=candy[i-1]+1;
                      }
                  }  
                  for(int j=ratings.length-1;j>0;j--){
                      if(ratings[j]<ratings[j-1]){
                          candy[j-1]=Math.max(candy[j-1],candy[j]+1);
                      }
                  }
                  for(int k=0;k<candy.length;k++){
                      count+=candy[k];
                  }
                  return count;
              }
          }

          執(zhí)行結果:

          分發(fā)糖果

          3、無重疊區(qū)間(435)

          題目描述:

          給定一個區(qū)間的集合,找到需要移除區(qū)間的最小數(shù)量,使剩余區(qū)間互不重疊。

          注意:可以認為區(qū)間的終點總是大于它的起點;區(qū)間[1,2]和[2,3]的邊界相互接觸,但沒有相互重疊

          示例:

          示例 1:

          輸入: [ [1,2], [2,3], [3,4], [1,3] ]

          輸出: 1

          解釋: 移除 [1,3] 后,剩下的區(qū)間沒有重疊。

          示例 2:

          輸入: [ [1,2], [1,2], [1,2] ]

          輸出: 2

          解釋: 你需要移除兩個 [1,2] 來使剩下的區(qū)間沒有重疊。

          示例 3:

          輸入: [ [1,2], [2,3] ]

          輸出: 0

          解釋: 你不需要移除任何區(qū)間,因為它們已經(jīng)是無重疊的了。

          解題思路:

          首先要對區(qū)間進行排序,本題采用的是對區(qū)間的頭元素進行排序,然后在遍歷空間

          • 如果后面區(qū)間的頭小于當前區(qū)間的尾,比如當前區(qū)間是[3,6],后面區(qū)間是[4,5]或者是[5,9],說明這兩個區(qū)間有重復,必須要移除一個,那么要移除哪個呢,為了防止在下一個區(qū)間和現(xiàn)有區(qū)間有重疊,我們應該讓現(xiàn)有區(qū)間越短越好,所以應該移除尾部比較大的,保留尾部比較小的。
          • 如果后面區(qū)間的頭不小于當前區(qū)間的尾,說明他們沒有重合,不需要移除

          代碼:

          class Solution {
              public int eraseOverlapIntervals(int[][] intervals) {
                  //對2*2數(shù)組按照左邊界排序
                  Arrays.sort(intervals,(a,b)->a[0]-b[0]);
                  int end=intervals[0][1];
                  int count=0;
                  for(int i=1;i<intervals.length;i++){
                      if(intervals[i][0]<end){
                          //區(qū)間有重疊,選取右邊界最小的數(shù)組
                          end=Math.min(end,intervals[i][1]);
                          count++;
                      }else{
                          //區(qū)間無重疊,直接更新就好
                          end=intervals[i][1];
                      }
                    
                  }
                  return count;
              }
          }

          執(zhí)行結果:

          無重疊區(qū)

          4、種花問題(605)

          題目描述:

          假設有一個很長的花壇,一部分地塊種植了花,另一部分卻沒有。可是,花不能種植在相鄰的地塊上,它們會爭奪水源,兩者都會死去。

          給你一個整數(shù)數(shù)組  flowerbed 表示花壇,由若干 0 和 1 組成,其中 0 表示沒種植花,1 表示種植了花。另有一個數(shù) n ,能否在不打破種植規(guī)則的情況下種入 n 朵花?能則返回 true ,不能則返回 false

          示例

          示例 1:

          輸入:flowerbed = [1,0,0,0,1], n = 1 輸出:true

          示例 2:

          輸入:flowerbed = [1,0,0,0,1], n = 2 輸出:false

          解題思路:

          題目要求是否能在不打破規(guī)則的情況下插入n朵花,與直接計算不同,采用“跳格子”的解法只需遍歷不到一遍數(shù)組,處理以下兩種不同的情況即可:

          • 當遍歷到index遇到1時,說明這個位置有花,那必然從index+2的位置才有可能種花,因此當碰到1時直接跳過下一格。
          • 當遍歷到index遇到0時,由于每次碰到1都是跳兩格,因此前一格必定是0,此時只需要判斷下一格是不是1即可得出index這一格能不能種花,如果能種則令n減一,然后這個位置就按照遇到1時處理,即跳兩格;如果index的后一格是1,說明這個位置不能種花且之后兩格也不可能種花,直接跳過3格。

          當n減為0時,說明可以種入n朵花,則可以直接退出遍歷返回true;如果遍歷結束n沒有減到0,說明最多種入的花的數(shù)量小于n,則返回false。

          代碼:

          class Solution {
              public boolean canPlaceFlowers(int[] flowerbed, int n) {
                   //采用跳格子的思想解決
                   //1,index為1,跳兩格
                   //2 index為0,證明前一個格子是0,只需要判斷下一個格子是否為0
                   //若為0,則n-1,
                   //若為1,則跳三格
                   for(int i=0;i<flowerbed.length && n>0;){
                       if(flowerbed[i]==1){
                           i=i+2;
                           //一定要注意邊界問題
                       } else if(i==flowerbed.length-1 || flowerbed[i+1]==0){
                              n--;
                              i=i+2;
                       }else{
                              i=i+3;
                          }
                   }
                   return n<=0;
              }
          }

          執(zhí)行結果:

          種花問題

          5、用最少數(shù)量的箭引爆氣球(452)

          題目描述:

          在二維空間中有許多球形的氣球。對于每個氣球,提供的輸入是水平方向上,氣球直徑的開始和結束坐標。由于它是水平的,所以縱坐標并不重要,因此只要知道開始和結束的橫坐標就足夠了。開始坐標總是小于結束坐標。

          一支弓箭可以沿著 x 軸從不同點完全垂直地射出。在坐標 x 處射出一支箭,若有一個氣球的直徑的開始和結束坐標為 xstart,xend, 且滿足  xstart ≤ x ≤ xend,則該氣球會被引爆。可以射出的弓箭的數(shù)量沒有限制。弓箭一旦被射出之后,可以無限地前進。我們想找到使得所有氣球全部被引爆,所需的弓箭的最小數(shù)量。

          給你一個數(shù)組 points ,其中 points [i] = [xstart,xend] ,返回引爆所有氣球所必須射出的最小弓箭數(shù)。

          示例

          示例 1:

          輸入:points = [[10,16],[2,8],[1,6],[7,12]] 輸出:2 解釋:對于該樣例,x = 6 可以射爆 [2,8],[1,6] 兩個氣球,以及 x = 11 射爆另外兩個氣球

          示例 2:

          輸入:points = [[1,2],[3,4],[5,6],[7,8]] 輸出:4

          示例 3:

          輸入:points = [[1,2],[2,3],[3,4],[4,5]] 輸出:2

          示例 4:

          輸入:points = [[1,2]] 輸出:1

          示例 5:

          輸入:points = [[2,3],[2,3]] 輸出:1

          解題思路:

          首先想到的思路是對數(shù)組中的區(qū)間值按左端點進行排序

          • 如果新氣球的左端點大于射擊區(qū)間的右邊界,那么我們就需要重新開辟一個區(qū)間;

          • 如果新氣球的左端點小于射擊區(qū)間的右邊界,這里又要分為兩種情況:如果右端點大于射擊區(qū)間的右邊界,那么我們的射擊區(qū)間的右邊界無需變化;如果右端點小于射擊區(qū)間的右邊界,那么我們射擊區(qū)間的右邊界就要向左移動,以新氣球的右端點為準,確立新的邊界。

          代碼:

          class Solution {
              public int findMinArrowShots(int[][] points) {
              //貪心算法,找出一支箭引爆最多的氣球的
                  if(points.length==0return 0;
              //對二維數(shù)組按照左邊界從小到大排休排序
              Arrays.sort(points,(a,b)->a[0]<b[0]?-1:1);
              int right=points[0][1];
              int count=1;
              for(int i=1;i<points.length;i++){
                  if(points[i][0]>right){
                      count++;
                      right=points[i][1];
                  }
                  else{
                      if(points[i][1]<right){
                          right=points[i][1];
                      }
                  }
              } 
              return count;
              }
          }

          執(zhí)行結果:

          用最少數(shù)量的箭引爆氣球

          6、劃分字母區(qū)間(763)

          題目描述:

          字符串 S 由小寫字母組成。我們要把這個字符串劃分為盡可能多的片段,同一字母最多出現(xiàn)在一個片段中。返回一個表示每個字符串片段的長度的列表。

          示例:

          輸入:S = "ababcbacadefegdehijhklij" 

          輸出:[9,7,8]

          解釋:劃分結果為 "ababcbaca", "defegde", "hijhklij"。每個字母最多出現(xiàn)在一個片段中。像 "ababcbacadefegde", "hijhklij" 的劃分是錯誤的,因為劃分的片段數(shù)較少。

          解題思路:

          由于同一個字母只能出現(xiàn)在同一個片段,顯然同一個字母的第一次出現(xiàn)的下標位置和最后一次出現(xiàn)的下標位置必須出現(xiàn)在同一個片段。因此需要遍歷字符串,得到每個字母最后一次出現(xiàn)的下標位置。

          在得到每個字母最后一次出現(xiàn)的下標位置之后,可以使用貪心的方法將字符串劃分為盡可能多的片段,具體做法如下。

          • 從左到右遍歷字符串,遍歷的同時維護當前片段的開始下標start和結束下標end,初始化start=end=0。
          • 對于每個訪問到的字母,得到當前字母的最后一次出現(xiàn)的下標位置end1,則當前片段的結束下標一定不會小于end1,因此,令end=max(end,end1)
          • 當訪問到下標end 時,當前片段訪問結束,當前片段的下標范圍是 [start,end],長度為end?start+1,將當前片段的長度添加到返回值,然后令 start=end+1,繼續(xù)尋找下一個片段
          • 重復上述過程,直至遍歷完字符串

          代碼:

          class Solution {
              public List<Integer> partitionLabels(String s) {
                  //先生成一個長度為26的數(shù)組,用于存放每個的不同字符在序列中的最終位置
                  int[] alphabet=new int[26];
                  List list=new ArrayList<>();
                  int start=0, end=0;
                  for(int i=0;i<s.length();i++){
                      alphabet[s.charAt(i)-'a']=i;
                  }

                  for(int i=0;i<s.length();i++){
                      end=Math.max(end,alphabet[s.charAt(i)-'a']);
                      if(end==i){
                          list.add(end-start+1);
                          start=end+1;
                      }
                  }
                  return list;
              }
          }

          執(zhí)行結果:

          劃分字母區(qū)間

          7、買賣股票的最佳時機(122)

          題目描述:

          給定一個數(shù)組 prices ,其中 prices[i] 是一支給定股票第 i 天的價格。設計一個算法來計算你所能獲取的最大利潤。你可以盡可能地完成更多的交易(多次買賣一支股票)。

          注意:你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。

          示例:

          示例 1:

          輸入: prices = [7,1,5,3,6,4] 

          輸出: 7 

          解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 3 天(股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。隨后,在第 4 天(股票價格 = 3)的時候買入,在第 5 天(股票價格 = 6)的時候賣出, 這筆交易所能獲得利潤 = 6-3 = 3 。 

          示例 2:

          輸入: prices = [1,2,3,4,5] 

          輸出: 4

          解釋: 在第 1 天(股票價格 = 1)的時候買入,在第 5 天 (股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。注意你不能在第 1 天和第 2 天接連購買股票,之后再將它們賣出。因為這樣屬于同時參與了多筆交易,你必須在再次購買前出售掉之前的股票。 

          示例 3:

          輸入: prices = [7,6,4,3,1]

          輸出: 0 

          解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。

          解題思路:

          • 由于該題可以買賣無限次,只要第二天的價格大于前一天的價格我們就買前一天的股票,然后在第二天賣掉,這樣我們就能從中獲取利潤;
          • 反之,如果第二天的價格小于前一天的價格我們就不進行買賣。

          代碼:

          class Solution {
              public int maxProfit(int[] prices) {
                  //
                  int sum=0;
                  int start=0, end=0;
                  for(int i=1;i<prices.length;i++){
                      if(prices[i]-prices[i-1]>0){
                          sum+=prices[i]-prices[i-1];
                      }
                  }
                  return sum;
              }
          }

          執(zhí)行結果

          買賣股票的最佳時機

          8、根據(jù)身高重建隊列(406)

          題目描述:

          假設有打亂順序的一群人站成一個隊列,數(shù)組 people 表示隊列中一些人的屬性(不一定按順序)。每個 people[i] = [hi, ki] 表示第 i 個人的身高為 hi ,前面 正好 有 ki 個身高大于或等于 hi 的人。

          請你重新構造并返回輸入數(shù)組 people 所表示的隊列。返回的隊列應該格式化為數(shù)組 queue ,其中 queue[j] = [hj, kj] 是隊列中第 j 個人的屬性(queue[0] 是排在隊列前面的人)。

          示例:

          示例 1:

          輸入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]] 

          輸出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 

          解釋:編號為 0 的人身高為 5 ,沒有身高更高或者相同的人排在他前面。編號為 1 的人身高為 7 ,沒有身高更高或者相同的人排在他前面。編號為 2 的人身高為 5 ,有 2 個身高更高或者相同的人排在他前面,即編號為 0 和 1 的人。編號為 3 的人身高為 6 ,有 1 個身高更高或者相同的人排在他前面,即編號為 1 的人。編號為 4 的人身高為 4 ,有 4 個身高更高或者相同的人排在他前面,即編號為 0、1、2、3 的人。編號為 5 的人身高為 7 ,有 1 個身高更高或者相同的人排在他前面,即編號為 1 的人。因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新構造后的隊列。

          示例 2:

          輸入:people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]] 

          輸出:[[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]

          解題思路:

          一般這種數(shù)對,還涉及排序的,根據(jù)第一個元素正向排序,根據(jù)第二個元素反向排序,或者根據(jù)第一個元素反向排序,根據(jù)第二個元素正向排序,往往能夠簡化解題過程。

          在本題目中,首先對數(shù)對進行排序,按照數(shù)對的元素 1 降序排序,按照數(shù)對的元素 2 升序排序。

          原因是:按照元素 1 進行降序排序,對于每個元素,在其之前的元素的個數(shù),就是大于等于他的元素的數(shù)量,而按照第二個元素正向排序,我們希望 k 大的盡量在后面,減少插入操作的次數(shù)。

          代碼:

          class Solution {
              public int[][] reconstructQueue(int[][] people) {
                // [7,0], [7,1], [6,1], [5,0], [5,2], [4,4]
                  // 再一個一個插入。
                  // [7,0]
                  // [7,0], [7,1]
                  // [7,0], [6,1], [7,1]
                  // [5,0], [7,0], [6,1], [7,1]
                  // [5,0], [7,0], [5,2], [6,1], [7,1]
                  // [5,0], [7,0], [5,2], [6,1], [4,4], [7,1]
                  Arrays.sort(people, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]);

                  LinkedList<int[]> list = new LinkedList<>();
                  for (int[] i : people) {
                      list.add(i[1], i);
                  }

                  return list.toArray(new int[list.size()][2]);
              }
          }

          執(zhí)行結果

          根據(jù)身高重建隊列

          9、非遞減數(shù)列(665)

          題目描述:

          給你一個長度為 n 的整數(shù)數(shù)組,請你判斷在 最多 改變 1 個元素的情況下,該數(shù)組能否變成一個非遞減數(shù)列。

          我們是這樣定義一個非遞減數(shù)列的:對于數(shù)組中任意的 i (0 <= i <= n-2),總滿足 nums[i] <= nums[i + 1]。

          示例:

          示例 1:

          輸入: nums = [4,2,3] 輸出: true 解釋: 你可以通過把第一個4變成1來使得它成為一個非遞減數(shù)列。

          示例 2:

          輸入: nums = [4,2,1] 輸出: false 解釋: 你不能在只改變一個元素的情況下將其變?yōu)榉沁f減數(shù)列。

          解題思路:

          本題是要維持一個非遞減的數(shù)列,所以遇到遞減的情況時(nums[i] > nums[i + 1]),要么將前面的元素縮小,要么將后面的元素放大。

          但是本題唯一的易錯點就在這,

          如果將nums[i]縮小,可能會導致其無法融入前面已經(jīng)遍歷過的非遞減子數(shù)列;如果將nums[i + 1]放大,可能會導致其后續(xù)的繼續(xù)出現(xiàn)遞減;所以要采取貪心的策略,在遍歷時,每次需要看連續(xù)的三個元素,也就是瞻前顧后,遵循以下兩個原則:

          需要盡可能不放大nums[i + 1],這樣會讓后續(xù)非遞減更困難;如果縮小nums[i],但不破壞前面的子序列的非遞減性;算法步驟:

          遍歷數(shù)組,如果遇到遞減:還能修改:

          修改方案1:將nums[i]縮小至nums[i + 1]

          修改方案2:將nums[i + 1]放大至nums[i];不能修改了:直接返回false

          代碼:

          class Solution {
              public boolean checkPossibility(int[] nums) {
                  if(nums.length==1return true;
                  boolean flag=nums[0]<=nums[1]?true:false;
                  for(int i=1;i<nums.length-1;i++){
                      if(nums[i+1]<nums[i]){
                          if(flag){
                              if(nums[i+1]>=nums[i-1])
                                  nums[i]=nums[i+1];
                              else
                                  nums[i+1]=nums[i];
                              flag=false;
                          }
                          else 
                             return false;
                      }
                  }
                  return true;
              }
          }

          執(zhí)行結果

          非遞減數(shù)列

          瀏覽 190
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  我要毛片毛片毛片毛片毛 | 中文字字幕在线中文乱码 | 国产在线无码视频56CC中文字幕 | 国产无遮挡又黄又爽又色视频 | 中文字幕无码一区二区三区一本久道不卡 |