• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 200, comments - 8, trackbacks - 0, articles - 0

                                程序員編程藝術(shù):第五章、尋找和為定值的兩個(gè)或多個(gè)數(shù)
             

                作者:July,yansha,zhouzhenren。
                致謝:微軟100題實(shí)現(xiàn)組,編程藝術(shù)室。
                微博:http://weibo.com/julyweibo   。
                出處:http://blog.csdn.net/v_JULY_v  。
                wiki:http://tctop.wikispaces.com/
            ------------------------------

            前奏

                希望此編程藝術(shù)系列能給各位帶來的是一種方法,一種創(chuàng)造力,一種舉一反三的能力。本章依然同第四章一樣,選取比較簡單的面試題,恭祝各位旅途愉快。同樣,有任何問題,歡迎不吝指正。謝謝。


            第一節(jié)、尋找和為定值的兩個(gè)數(shù)
            第14題(數(shù)組):
            題目:輸入一個(gè)數(shù)組和一個(gè)數(shù)字,在數(shù)組中查找兩個(gè)數(shù),使得它們的和正好是輸入的那個(gè)數(shù)字。
            要求時(shí)間復(fù)雜度是O(n)。如果有多對數(shù)字的和等于輸入的數(shù)字,輸出任意一對即可。
            例如輸入數(shù)組1、2、4、7、11、15和數(shù)字15。由于4+11=15,因此輸出4和11。

            分析

            咱們試著一步一步解決這個(gè)問題(注意闡述中數(shù)列有序無序的區(qū)別):

            1. 直接窮舉,從數(shù)組中任意選取兩個(gè)數(shù),判定它們的和是否為輸入的那個(gè)數(shù)字。此舉復(fù)雜度為O(N^2)。很顯然,我們要尋找效率更高的解法。
            2. 題目相當(dāng)于,對每個(gè)a[i],然后查找判斷sum-a[i]是否也在原始序列中,每一次要查找的時(shí)間都要花費(fèi)為O(N),這樣下來,最終找到兩個(gè)數(shù)還是需要O(N^2)的復(fù)雜度。那如何提高查找判斷的速度列?對了,二分查找,將原來O(N)的查找時(shí)間提高到O(logN),這樣對于N個(gè)a[i],都要花logN的時(shí)間去查找相對應(yīng)的sum-a[i]是否在原始序列中,總的時(shí)間復(fù)雜度已降為O(N*logN),且空間復(fù)雜度為O(1)。(如果有序,直接二分O(N*logN),如果無序,先排序后二分,復(fù)雜度同樣為O(N*logN+N*logN)=O(N*logN),空間總為O(1))。
            3. 有沒有更好的辦法列?咱們可以依據(jù)上述思路2的思想,a[i]在序列中,如果a[i]+a[k]=sum的話,那么sum-a[i](a[k])也必然在序列中,,舉個(gè)例子,如下:
              原始序列:1、 2、 4、 7、11、15     用輸入數(shù)字15減一下各個(gè)數(shù),得到對應(yīng)的序列為:
              對應(yīng)序列:14、13、11、8、4、 0      
              第一個(gè)數(shù)組以一指針i 從數(shù)組最左端開始向右掃描,第二個(gè)數(shù)組以一指針j 從數(shù)組最右端開始向左掃描,如果下面出現(xiàn)了和上面一樣的數(shù),即a[*i]=a[*j],就找出這倆個(gè)數(shù)來了。如上,i,j最終在第一個(gè),和第二個(gè)序列中找到了相同的數(shù)4和11,,所以符合條件的兩個(gè)數(shù),即為4+11=15。怎么樣,兩端同時(shí)查找,時(shí)間復(fù)雜度瞬間縮短到了O(N),但卻同時(shí)需要O(N)的空間存儲第二個(gè)數(shù)組(@飛羽:要達(dá)到O(N)的復(fù)雜度,第一個(gè)數(shù)組以一指針i 從數(shù)組最左端開始向右掃描,第二個(gè)數(shù)組以一指針j 從數(shù)組最右端開始向左掃描,首先初始i指向元素1,j指向元素0,誰指的元素小,誰先移動,由于1(i)>0(j),所以i不動,j向左移動。然后j移動到元素4發(fā)現(xiàn)大于元素1,故而停止移動j,開始移動i,直到i指向4,這時(shí),i指向的元素與j指向的元素相等,故而判斷4是滿足條件的第一個(gè)數(shù);然后同時(shí)移動i,j再進(jìn)行判斷,直到它們到達(dá)邊界)。
            4. 當(dāng)然,你還可以構(gòu)造hash表,正如編程之美上的所述,給定一個(gè)數(shù)字,根據(jù)hash映射查找另一個(gè)數(shù)字是否也在數(shù)組中,只需用O(1)的時(shí)間,這樣的話,總體的算法通上述思路3 一樣,也能降到O(N),但有個(gè)缺陷,就是構(gòu)造hash額外增加了O(N)的空間,此點(diǎn)同上述思路 3。不過,空間換時(shí)間,仍不失為在時(shí)間要求較嚴(yán)格的情況下的一種好辦法。
            5. 如果數(shù)組是無序的,先排序(n*logn),然后用兩個(gè)指針i,j,各自指向數(shù)組的首尾兩端,令i=0,j=n-1,然后i++,j--,逐次判斷a[i]+a[j]?=sum,如果某一刻a[i]+a[j]>sum,則要想辦法讓sum的值減小,所以此刻i不動,j--,如果某一刻a[i]+a[j]<sum,則要想辦法讓sum的值增大,所以此刻i++,j不動。所以,數(shù)組無序的時(shí)候,時(shí)間復(fù)雜度最終為O(n*logn+n)=O(n*logn),若原數(shù)組是有序的,則不需要事先的排序,直接O(n)搞定,且空間復(fù)雜度還是O(1),此思路是相對于上述所有思路的一種改進(jìn)。(如果有序,直接兩個(gè)指針兩端掃描,時(shí)間O(N),如果無序,先排序后兩端掃描,時(shí)間O(N*logN+N)=O(N*logN),空間始終都為O(1))。(與上述思路2相比,排序后的時(shí)間開銷由之前的二分的n*logn降到了掃描的O(N))。

            總結(jié)

            • 不論原序列是有序還是無序,解決這類題有以下三種辦法:1、二分(若無序,先排序后二分),時(shí)間復(fù)雜度總為O(n*logn),空間復(fù)雜度為O(1);2、掃描一遍X-S[i]  映射到一個(gè)數(shù)組或構(gòu)造hash表,時(shí)間復(fù)雜度為O(n),空間復(fù)雜度為O(n);3、兩個(gè)指針兩端掃描(若無序,先排序后掃描),時(shí)間復(fù)雜度最后為:有序O(n),無序O(n*logn+n)=O(n*logn),空間復(fù)雜度都為O(1)。
            • 所以,要想達(dá)到時(shí)間O(N),空間O(1)的目標(biāo),除非原數(shù)組是有序的(指針掃描法),不然,當(dāng)數(shù)組無序的話,就只能先排序,后指針掃描法或二分(時(shí)間n*logn,空間O(1)),或映射或hash(時(shí)間O(n),空間O(n))。時(shí)間或空間,必須犧牲一個(gè),自個(gè)權(quán)衡吧。
            • 綜上,若是數(shù)組有序的情況下,優(yōu)先考慮兩個(gè)指針兩端掃描法,以達(dá)到最佳的時(shí)(O(N)),空(O(1))效應(yīng)。否則,如果要排序的話,時(shí)間復(fù)雜度最快當(dāng)然是只能達(dá)到N*logN,空間O(1)則是不在話下。

            代碼:

            ok,在進(jìn)入第二節(jié)之前,咱們先來實(shí)現(xiàn)思路5(這里假定數(shù)組已經(jīng)是有序的),代碼可以如下編寫(兩段代碼實(shí)現(xiàn)):

            1. //代碼一  
            2. //O(N)  
            3. Pair findSum(int *s,int n,int x)     
            4. {     
            5.     //sort(s,s+n);   如果數(shù)組非有序的,那就事先排好序O(N*logN)     
            6.       
            7.     int *begin=s;     
            8.     int *end=s+n-1;     
            9.       
            10.     while(begin<end)    //倆頭夾逼,或稱兩個(gè)指針兩端掃描法,很經(jīng)典的方法,O(N)    
            11.     {     
            12.         if(*begin+*end>x)     
            13.         {     
            14.             --end;     
            15.         }     
            16.         else if(*begin+*end<x)     
            17.         {     
            18.             ++begin;     
            19.         }     
            20.         else    
            21.         {     
            22.             return Pair(*begin,*end);     
            23.         }     
            24.     }     
            25.       
            26.     return Pair(-1,-1);     
            27. }     
            28.   
            29. //或者如下編寫,  
            30. //代碼二  
            31. //copyright@ zhedahht && yansha  
            32. //July、updated,2011.05.14。  
            33. bool find_num(int data[], unsigned int length, int sum, int& first_num, int& second_num)  
            34. {     
            35.     if(length < 1)  
            36.         return true;  
            37.       
            38.     int begin = 0;  
            39.     int end = length - 1;  
            40.       
            41.     while(end > begin)  
            42.     {  
            43.         long current_sum = data[begin] + data[end];  
            44.           
            45.         if(current_sum == sum)  
            46.         {  
            47.             first_num = data[begin];  
            48.             second_num = data[end];  
            49.             return true;  
            50.         }  
            51.         else if(current_sum > sum)  
            52.             end--;  
            53.         else  
            54.             begin++;  
            55.     }  
            56.     return false;  
            57. }  

             

             

            擴(kuò)展:
            1、如果在返回找到的兩個(gè)數(shù)的同時(shí),還要求你返回這兩個(gè)數(shù)的位置列?
            2、如果把題目中的要你尋找的兩個(gè)數(shù)改為“多個(gè)數(shù)”,或任意個(gè)數(shù)列?(請看下面第二節(jié))
            3、二分查找時(shí): left <= right,right = middle - 1;left < right,right = middle;

             

            //算法所操作的區(qū)間,是左閉右開區(qū)間,還是左閉右閉區(qū)間,這個(gè)區(qū)間,需要在循環(huán)初始化,
            //循環(huán)體是否終止的判斷中,以及每次修改left,right區(qū)間值這三個(gè)地方保持一致,否則就可能出錯(cuò).

            //二分查找實(shí)現(xiàn)一
            int search(int array[], int n, int v)
            {
                int left, right, middle;
             
                left = 0, right = n - 1;
             
                while (left <= right)
                {
                    middle = left + (right-left)/2;   
                    if (array[middle] > v)
                    {
                        right = middle - 1;
                    }
                    else if (array[middle] < v)
                    {
                        left = middle + 1;
                    }
                    else
                    {
                        return middle;
                    }
                }
             
                return -1;
            }

            //二分查找實(shí)現(xiàn)二
            int search(int array[], int n, int v)
            {
                int left, right, middle;
             
                left = 0, right = n;
             
                while (left < right)
                {
                    middle = left + (right-left)/2;    
              
                    if (array[middle] > v)
                    {
                        right = middle;
                    }
                    else if (array[middle] < v)
                    {
                        left = middle + 1;
                    }
                    else
                    {
                        return middle;
                    }
                }
             
                return -1;
            }


            第二節(jié)、尋找和為定值的多個(gè)數(shù)
            第21題(數(shù)組)
            2010年中興面試題
            編程求解:
            輸入兩個(gè)整數(shù) n 和 m,從數(shù)列1,2,3.......n 中 隨意取幾個(gè)數(shù),
            使其和等于 m ,要求將其中所有的可能組合列出來。

            解法一
            我想,稍后給出的程序已經(jīng)足夠清楚了,就是要注意到放n,和不放n個(gè)區(qū)別,即可,代碼如下:

            1. // 21題遞歸方法  
            2. //copyright@ July && yansha  
            3. //July、yansha,updated。  
            4. #include<list>  
            5. #include<iostream>  
            6. using namespace std;  
            7.   
            8. list<int>list1;  
            9. void find_factor(int sum, int n)   
            10. {  
            11.     // 遞歸出口  
            12.     if(n <= 0 || sum <= 0)  
            13.         return;  
            14.       
            15.     // 輸出找到的結(jié)果  
            16.     if(sum == n)  
            17.     {  
            18.         // 反轉(zhuǎn)list  
            19.         list1.reverse();  
            20.         for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)  
            21.             cout << *iter << " + ";  
            22.         cout << n << endl;  
            23.         list1.reverse();      
            24.     }  
            25.       
            26.     list1.push_front(n);      //典型的01背包問題  
            27.     find_factor(sum-n, n-1);   //放n,n-1個(gè)數(shù)填滿sum-n  
            28.     list1.pop_front();  
            29.     find_factor(sum, n-1);     //不放n,n-1個(gè)數(shù)填滿sum   
            30. }  
            31.   
            32. int main()  
            33. {  
            34.     int sum, n;  
            35.     cout << "請輸入你要等于多少的數(shù)值sum:" << endl;  
            36.     cin >> sum;  
            37.     cout << "請輸入你要從1.....n數(shù)列中取值的n:" << endl;  
            38.     cin >> n;  
            39.     cout << "所有可能的序列,如下:" << endl;  
            40.     find_factor(sum,n);  
            41.     return 0;  
            42. }  

             

            解法二
            @zhouzhenren:
            這個(gè)問題屬于子集和問題(也是背包問題)。本程序采用 回溯法+剪枝
            X數(shù)組是解向量,t=∑(1,..,k-1)Wi*Xi, r=∑(k,..,n)Wi
            若t+Wk+W(k+1)<=M,則Xk=true,遞歸左兒子(X1,X2,..,X(k-1),1);否則剪枝;
            若t+r-Wk>=M && t+W(k+1)<=M,則置Xk=0,遞歸右兒子(X1,X2,..,X(k-1),0);否則剪枝;
            本題中W數(shù)組就是(1,2,..,n),所以直接用k代替WK值。

            代碼編寫如下:

            1. //copyright@ 2011 zhouzhenren  
            2.   
            3. //輸入兩個(gè)整數(shù) n 和 m,從數(shù)列1,2,3.......n 中 隨意取幾個(gè)數(shù),  
            4. //使其和等于 m ,要求將其中所有的可能組合列出來。  
            5.   
            6. #include <stdio.h>  
            7. #include <stdlib.h>  
            8. #include <memory.h>  
            9.   
            10. /**  
            11.  * 輸入t, r, 嘗試Wk 
            12.  */  
            13. void sumofsub(int t, int k ,int r, int& M, bool& flag, bool* X)  
            14. {  
            15.     X[k] = true;   // 選第k個(gè)數(shù)  
            16.     if (t + k == M) // 若找到一個(gè)和為M,則設(shè)置解向量的標(biāo)志位,輸出解  
            17.     {  
            18.         flag = true;  
            19.         for (int i = 1; i <= k; ++i)  
            20.         {  
            21.             if (X[i] == 1)  
            22.             {  
            23.                 printf("%d ", i);  
            24.             }  
            25.         }  
            26.         printf("/n");  
            27.     }  
            28.     else  
            29.     {   // 若第k+1個(gè)數(shù)滿足條件,則遞歸左子樹  
            30.         if (t + k + (k+1) <= M)  
            31.         {  
            32.             sumofsub(t + k, k + 1, r - k, M, flag, X);  
            33.         }  
            34.         // 若不選第k個(gè)數(shù),選第k+1個(gè)數(shù)滿足條件,則遞歸右子樹  
            35.         if ((t + r - k >= M) && (t + (k+1) <= M))  
            36.         {  
            37.             X[k] = false;  
            38.             sumofsub(t, k + 1, r - k, M, flag, X);  
            39.         }  
            40.     }  
            41. }  
            42.   
            43. void search(int& N, int& M)  
            44. {  
            45.     // 初始化解空間  
            46.     bool* X = (bool*)malloc(sizeof(bool) * (N+1));  
            47.     memset(X, falsesizeof(bool) * (N+1));  
            48.     int sum = (N + 1) * N * 0.5f;  
            49.     if (1 > M || sum < M) // 預(yù)先排除無解情況  
            50.     {  
            51.         printf("not found/n");  
            52.         return;  
            53.     }  
            54.     bool f = false;  
            55.     sumofsub(0, 1, sum, M, f, X);  
            56.     if (!f)  
            57.     {  
            58.         printf("not found/n");  
            59.     }  
            60.     free(X);  
            61. }  
            62.   
            63. int main()  
            64. {  
            65.     int N, M;  
            66.     printf("請輸入整數(shù)N和M/n");  
            67.     scanf("%d%d", &N, &M);  
            68.     search(N, M);  
            69.     return 0;  
            70. }  

             

            擴(kuò)展:

            1、從一列數(shù)中篩除盡可能少的數(shù)使得從左往右看,這些數(shù)是從小到大再從大到小的(網(wǎng)易)。

            2、有兩個(gè)序列a,b,大小都為n,序列元素的值任意整數(shù),無序;
            要求:通過交換a,b中的元素,使[序列a元素的和]與[序列b元素的和]之間的差最小。
            例如:  
            var a=[100,99,98,1,2, 3];
            var b=[1, 2, 3, 4,5,40];(微軟100題第32題)。

                @well:[fairywell]:
            給出擴(kuò)展問題 1 的一個(gè)解法:
            1、從一列數(shù)中篩除盡可能少的數(shù)使得從左往右看,這些數(shù)是從小到大再從大到小的(網(wǎng)易)。
            雙端 LIS 問題,用 DP 的思想可解,目標(biāo)規(guī)劃函數(shù) max{ b[i] + c[i] - 1 }, 其中 b[i] 為從左到右, 0 ~ i 個(gè)數(shù)之間滿足遞增的數(shù)字個(gè)數(shù); c[i] 為從右到左, n-1 ~ i 個(gè)數(shù)之間滿足遞增的數(shù)字個(gè)數(shù)。最后結(jié)果為 n - max + 1。其中 DP 的時(shí)候,可以維護(hù)一個(gè) inc[] 數(shù)組表示遞增數(shù)字序列,inc[i] 為從小到大第 i 大的數(shù)字,然后在計(jì)算 b[i] c[i] 的時(shí)候使用二分查找在 inc[] 中找出區(qū)間 inc[0] ~ inc[i-1] 中小于 a[i] 的元素個(gè)數(shù)(low)。
            源代碼如下:

            1. /** 
            2. * The problem: 
            3. * 從一列數(shù)中篩除盡可能少的數(shù)使得從左往右看,這些數(shù)是從小到大再從大到小的(網(wǎng)易)。 
            4. * use binary search, perhaps you should compile it with -std=c99 
            5. * fairywell 2011 
            6. */  
            7. #include <stdio.h>  
            8.   
            9. #define MAX_NUM    (1U<<31)  
            10.   
            11. int  
            12. main()  
            13. {  
            14.     int i, n, low, high, mid, max;  
            15.       
            16.     printf("Input how many numbers there are: ");  
            17.     scanf("%d/n", &n);  
            18.     /* a[] holds the numbers, b[i] holds the number of increasing numbers 
            19.     * from a[0] to a[i], c[i] holds the number of increasing numbers 
            20.     * from a[n-1] to a[i] 
            21.     * inc[] holds the increasing numbers 
            22.     * VLA needs c99 features, compile with -stc=c99 
            23.     */  
            24.     double a[n], b[n], c[n], inc[n];  
            25.       
            26.     printf("Please input the numbers:/n");  
            27.     for (i = 0; i < n; ++i) scanf("%lf", &a[i]);  
            28.       
            29.     // update array b from left to right  
            30.     for (i = 0; i < n; ++i) inc[i] = (unsigned) MAX_NUM;  
            31.     //b[0] = 0;  
            32.     for (i = 0; i < n; ++i) {  
            33.         low = 0; high = i;  
            34.         while (low < high) {  
            35.             mid = low + (high-low)*0.5;  
            36.             if (inc[mid] < a[i]) low = mid + 1;  
            37.             else high = mid;  
            38.         }  
            39.         b[i] = low + 1;  
            40.         inc[low] = a[i];  
            41.     }  
            42.       
            43.     // update array c from right to left  
            44.     for (i = 0; i < n; ++i) inc[i] = (unsigned) MAX_NUM;  
            45.     //c[0] = 0;  
            46.     for (i = n-1; i >= 0; --i) {  
            47.         low = 0; high = i;  
            48.         while (low < high) {  
            49.             mid = low + (high-low)*0.5;  
            50.             if (inc[mid] < a[i]) low = mid + 1;  
            51.             else high = mid;  
            52.         }  
            53.         c[i] = low + 1;  
            54.         inc[low] = a[i];  
            55.     }  
            56.       
            57.     max = 0;  
            58.     for (i = 0; i < n; ++i )  
            59.         if (b[i]+c[i] > max) max = b[i] + c[i];  
            60.         printf("%d number(s) should be erased at least./n", n+1-max);  
            61.         return 0;  
            62. }  

             

            @yansha:fairywell的程序很贊,時(shí)間復(fù)雜度O(nlogn),這也是我能想到的時(shí)間復(fù)雜度最優(yōu)值了。不知能不能達(dá)到O(n)。

            擴(kuò)展題第2題

            當(dāng)前數(shù)組a和數(shù)組b的和之差為
                A = sum(a) - sum(b)

            a的第i個(gè)元素和b的第j個(gè)元素交換后,a和b的和之差為
                A' = sum(a) - a[i] + b[j] - (sum(b) - b[j] + a[i])
                       = sum(a) - sum(b) - 2 (a[i] - b[j])
                       = A - 2 (a[i] - b[j])

            設(shè)x = a[i] - b[j],得
                |A| - |A'| = |A| - |A-2x|

                假設(shè)A > 0,

                當(dāng)x 在 (0,A)之間時(shí),做這樣的交換才能使得交換后的a和b的和之差變小,x越接近A/2效果越好,
                如果找不到在(0,A)之間的x,則當(dāng)前的a和b就是答案。

            所以算法大概如下:
                在a和b中尋找使得x在(0,A)之間并且最接近A/2的i和j,交換相應(yīng)的i和j元素,重新計(jì)算A后,重復(fù)前面的步驟直至找不到(0,A)之間的x為止。 

            接上,@yuan:
            a[i]-b[j]要接近A/2,則可以這樣想,
            我們可以對于a數(shù)組的任意一個(gè)a[k],在數(shù)組b中找出與a[k]-C最接近的數(shù)(C就是常數(shù),也就是0.5*A)
            這個(gè)數(shù)要么就是a[k]-C,要么就是比他稍大,要么比他稍小,所以可以要二分查找。

            查找最后一個(gè)小于等于a[k]-C的數(shù)和第一個(gè)大于等于a[k]-C的數(shù),
            然后看哪一個(gè)與a[k]-C更加接近,所以T(n) = nlogn。

            除此之外,受本文讀者xiafei1987128啟示,有朋友在stacoverflow上也問過一個(gè)類似的題,:-),見此:http://stackoverflow.com/questions/9047908/swap-the-elements-of-two-sequences-such-that-the-difference-of-the-element-sums。感興趣的可以看看。

            本章完。


             

            程序員面試題狂想曲-tctop(the crazy thinking of programers)的修訂wiki(http://tctop.wikispaces.com/)已建立,我們急切的想得到讀者的反饋,意見,建議,以及更好的思路,算法,和代碼優(yōu)化的建議。所以,

            •如果你發(fā)現(xiàn)了狂想曲系列中的任何一題,任何一章(http://t.cn/hgVPmH)中的錯(cuò)誤,問題,與漏洞,歡迎告知給我們,我們將感激不盡,同時(shí),免費(fèi)贈送本blog內(nèi)的全部博文集錦的CHM文件1期;
            •如果你能對狂想曲系列的創(chuàng)作提供任何建設(shè)性意見,或指導(dǎo),歡迎反饋給我們,并真誠邀請您加入到狂想曲的wiki修訂工作中;
            •如果你是編程高手,對狂想曲的任何一章有自己更好的思路,或算法,歡迎加入狂想曲的創(chuàng)作組,以為千千萬萬的讀者創(chuàng)造更多的價(jià)值,更好的服務(wù)。
            Ps:狂想曲tctop的wiki修訂地址為:http://tctop.wikispaces.com/
            。歡迎圍觀,更歡迎您加入到狂想曲的創(chuàng)作或wiki修訂中。 

            版權(quán)所有,本人對本blog內(nèi)所有任何內(nèi)容享有版權(quán)及著作權(quán)。實(shí)要轉(zhuǎn)載,請以鏈接形式注明出處。

            久久久久久国产a免费观看不卡| 2021国产精品午夜久久| 99久久精品无码一区二区毛片| 激情久久久久久久久久| 久久久无码精品亚洲日韩京东传媒 | 久久精品国产亚洲AV忘忧草18| 精品国产乱码久久久久久1区2区| 久久精品国产亚洲AV不卡| 日韩人妻无码精品久久久不卡| 国产99久久久国产精免费| 97精品国产97久久久久久免费 | 亚洲精品午夜国产VA久久成人| 久久精品成人欧美大片| 丁香狠狠色婷婷久久综合| 国产精品久久久香蕉| 久久99国产精品成人欧美| 久久成人精品视频| 久久久久99精品成人片欧美 | 亚洲成色999久久网站| 久久国产高潮流白浆免费观看| 亚洲国产成人乱码精品女人久久久不卡 | 精品无码久久久久国产动漫3d| 久久精品国产99久久香蕉| 久久福利青草精品资源站免费| 无码人妻久久一区二区三区免费 | 51久久夜色精品国产| 久久国产高清字幕中文| 色婷婷综合久久久久中文 | 国产成人精品久久亚洲高清不卡| 成人综合伊人五月婷久久| 久久亚洲精品人成综合网| 婷婷久久久亚洲欧洲日产国码AV | 久久99精品综合国产首页| 久久精品九九亚洲精品天堂| 久久亚洲春色中文字幕久久久| 日本人妻丰满熟妇久久久久久| 狠狠综合久久综合88亚洲| 久久亚洲国产精品成人AV秋霞| 久久无码中文字幕东京热| 久久久久人妻一区二区三区| 国产69精品久久久久APP下载 |