亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? xsudoku.cpp

?? 數獨快速并行求解算法
?? CPP
字號:
/*/////////////////////////////////////////
// 版權所有(C)  2000-2008 鄧輝           //
// Email:      denghui0815@hotmail.com  //
// 說明:       Intel線程優化大賽參賽作品//
/////////////////////////////////////////*/

#include "XSudoku.h"

// 包含1的個數 
// 小于XFILLEDMASK為正常值
// 大于等于XFILLEDMASK值均為255  [XFindMinFeasibilityPos中減少判斷]
__declspec(align(16)) uint8  g_xPopCnt[0xFFFF] = {0};
// 單元格的值到輸出字符的映射
__declspec(align(16)) char   g_xOutTab[1 << XGRID_BSIZE] = {0};
// 輸出緩沖
__declspec(align(16)) char   g_xOutCells[XGRID_BSIZE + XGRID_BW + 1][(XGRID_BSIZE + XGRID_BH) * 2 + 2] = {0};

// 保存與當前單元格相關的單元格
__declspec(align(16)) uint8  g_xMutuality[XGRID_AREA][XGRID_MUTUALITYSSE] = {0};
__declspec(align(16)) uint8  g_nMutuality[XGRID_AREA] = {0};

// 初始化靜態加速Tab
void XInitTab()
{
	int i,j;

	// 初始化PopCnt數組
	g_xPopCnt[0] = 0;
	g_xPopCnt[1] = 1;
	g_xPopCnt[2] = 1;
	g_xPopCnt[3] = 2;

	for(i = 0x04;  i < 0x10;  ++i)   g_xPopCnt[i] = g_xPopCnt[i >> 2] + g_xPopCnt[i & 0x03];
	for(i = 0x10;  i < 0x100; ++i)   g_xPopCnt[i] = g_xPopCnt[i >> 4] + g_xPopCnt[i & 0x0F];
#pragma omp parallel for
	for(i = 0x100; i < XFILLEDMASK; ++i) g_xPopCnt[i] = g_xPopCnt[i >> 8] + g_xPopCnt[i & 0xFF];
#pragma omp parallel for
	// 已填值的特殊處理
	for(i = XFILLEDMASK; i < 0x10000; ++i) g_xPopCnt[i] = 0xFF;

	// 計算每個單元格的關聯單元格數組
	for(i = 0; i < XGRID_AREA; ++i)
	{
		g_nMutuality[i] = 0;

		for(j = 0; j < XGRID_AREA; ++j)
		{
			if(i == j) continue;

			// 如果兩個單元格滿足以下條件 則這兩個單元格存在關聯關系
			// 1. 單元格的橫坐標相同 
			// 2. 單元格的縱坐標相同
			// 3. 單元格所在塊的橫坐標相同且單元格所在塊的縱坐標相同[兩個單元格在同一個塊中]
			if( ( i % XGRID_BSIZE == j % XGRID_BSIZE ) || ( i / XGRID_BSIZE == j / XGRID_BSIZE ) || 
				( ( i / XGRID_BSIZE / XGRID_BH  == j / XGRID_BSIZE / XGRID_BH ) && 
				( ( i % XGRID_BSIZE ) / XGRID_BW ) == ( ( j % XGRID_BSIZE ) / XGRID_BW ) ) )
			{
				g_xMutuality[i][g_nMutuality[i]++] = j;
			}
		}

		for(j = XGRID_MUTUALITY; j < XGRID_MUTUALITYSSE; ++j)  g_xMutuality[i][j] = XGRID_AREA;
	}

	// 初始化值到字符的映射
	for(i = 0; i < XGRID_BSIZE; ++i) g_xOutTab[ 1 << i] = i + '1';

	// 初始化輸出字符表格
	for(i = 0; i < XGRID_BSIZE + XGRID_BW + 1; ++i)
	{
		if(i % (XGRID_BH + 1) == 0)
		{
			for(j = 0; j < (XGRID_BSIZE + XGRID_BH) * 2 + 1; ++j)
			{
				g_xOutCells[i][j] =  (j % (XGRID_BW * 2 + 2) == 0) ? '+' : '-';
			}
		}
		else
		{
			for(j = 0; j < (XGRID_BSIZE + XGRID_BH) * 2 + 1; ++j)
			{
				g_xOutCells[i][j] =  (j % (XGRID_BW * 2 + 2) == 0) ? '|' : ' ';
			}
		}

		g_xOutCells[i][(XGRID_BSIZE + XGRID_BH) * 2 + 1] =  (i == XGRID_BSIZE + XGRID_BW) ? '\0' : '\n';
	}
}

// 輸出網格
__inline void XAddSolution(int* pRunMode, int* pTotal, XCells pCells)
{
#ifndef XOUT_SOLUTION
	if(++(*pTotal) > 1)
	{
		*pRunMode &= ~XRUN_FIND_FLAG;
	}
#else
	static mutex xMutex;

	if(*pRunMode & XRUN_FIND_ONE)
	{
		if(++(*pTotal) > 1)
		{
			*pRunMode &= ~XRUN_FIND_FLAG;
		}
	}
	else
	{
		tbb::mutex::scoped_lock lock(xMutex);

		++(*pTotal);
	}

	if(*pRunMode & (XRUN_OUT_STD | XRUN_OUT_FILE))
	{
		for(int nPos = 0; nPos < XGRID_AREA; ++nPos)
		{
			int x = nPos % XGRID_BSIZE;
			int y = nPos / XGRID_BSIZE;
			g_xOutCells[y + y / XGRID_BH + 1][(x + x / XGRID_BW + 1) * 2] = g_xOutTab[pCells[nPos] - XFILLEDMASK];
		}

		if(*pRunMode & XRUN_OUT_STD) 
		{
			printf("第%d種\n%s\n\n", *pTotal, (const char*)g_xOutCells);
		}
		else
		{
			FILE* fp = fopen("xout.txt", "a");
			fprintf(fp, "第%d種\n%s\n\n", *pTotal, (const char*)g_xOutCells);
			fclose(fp);
		}
	}
#endif
}


// 為nPos位置的單元格置上nMask表示的值
// 當某個關聯單元格清除后僅剩下一種可能性則繼續遞歸調用XFillCell填充掉該單元格
// 將填充的單元格位置保存到pGrid->pFilledPos中
__inline int XFillCell(XGrid* pGrid, XCells pCells, int nPos, int nMask)
{
	int nFilled = pGrid->nFilled;

	for(;;)
	{
#ifdef XGRID_MUTUALITYSSE_CLEAR
		uint8* const pMutuality = pGrid->pMutuality[nPos];
		const uint8  nMutuality = pGrid->nMutuality[nPos];
#else
		uint8* const pMutuality = g_xMutuality[nPos];
		const uint8  nMutuality = g_nMutuality[nPos];
#endif

		pCells[nPos] = nMask + XFILLEDMASK;

		pGrid->pFilledPos[nFilled++] = nPos;

		nPos = -1;

#pragma unroll(16)
		for(int i = 0; i < nMutuality; ++i)
		{
			const uint8 nTmp = pMutuality[i];

			// 去掉該單元格填充nMask的可能性
			pCells[nTmp] &= ~nMask;

			// 如果單元格沒有可選擇的填值方案 返回失敗
			if(pCells[nTmp] == 0) return XFILL_INVALID;

			// 判斷該單元格是否只有一種填值可能,如果是將調用XFillCell給該單元格填值
			if(g_xPopCnt[pCells[nTmp]] == 1) nPos = nTmp;
		}

		if(nPos < 0) break;

		nMask = pCells[nPos];
	}

	pGrid->nFilled = nFilled;
	
	return pGrid->nFilled;
}

__inline int XFillCellLoad(XGrid* pGrid, XCells pCells, int nPos, int nMask)
{
	int nNewPos = -1;
#ifdef XGRID_MUTUALITYSSE_CLEAR
	uint8* const pMutuality = pGrid->pMutuality[nPos];
	const uint8  nMutuality = pGrid->nMutuality[nPos];
#else
	uint8* const pMutuality = g_xMutuality[nPos];
	const uint8  nMutuality = g_nMutuality[nPos];
#endif

	// 如果該單元格已經填充了nMask 直接返回
	if(pCells[nPos] == nMask + XFILLEDMASK) return pGrid->nFilled;

	// 判斷當前單元格能填nMask表示的值
	if((pCells[nPos] & nMask) == 0) return XFILL_INVALID;

	// 為第nPos個單元格填上nMask表示的值
	pCells[nPos] = nMask + XFILLEDMASK;

	for(int i = 0; i < nMutuality; ++i)
	{
		const uint8 nTmp = pMutuality[i];

		// 去掉該單元格填充nMask的可能性
		pCells[nTmp] &= ~nMask;

		// 如果單元格沒有可選擇的填值方案 返回失敗
		if(pCells[nTmp] == 0) return XFILL_INVALID;

		// 判斷該單元格是否只有一種填值可能,如果是將調用XFillCell給該單元格填值
		if(g_xPopCnt[pCells[nTmp]] == 1) nNewPos = nTmp;
	}

	// 記錄當前填充的單元格
	pGrid->pFilledPos[pGrid->nFilled++] = nPos;

	if(nNewPos >= 0) 
	{
		if(XFillCell(pGrid, pCells, nNewPos, pCells[nNewPos]) == XFILL_INVALID)
		{
			// 恢復已經填值的單元格
			--pGrid->nFilled;

			return XFILL_INVALID;
		}
	}

	return pGrid->nFilled;
}


// 查找可填的數字最少的單元格
__inline int XFindMinFeasibilityPos(XCells pCells)
{
	int nMinCnt = 0xFF;
	int nMinPos = -1;

	// 在所有未填值的單元格中查找可填值方案最少的單元格
	for(int i = 0; i < XGRID_AREA && nMinCnt > 1; ++i)
	{
		if(g_xPopCnt[pCells[i]] < nMinCnt)
		{
			nMinPos = i;
			nMinCnt = g_xPopCnt[pCells[i]];
		}
	}

	return nMinPos;
}

// 刪除與單元格nPos相關聯的單元格 [XGRID_BSIZE>=9且需要查找所有情況時清除關聯可加速]
#ifdef XGRID_MUTUALITYSSE_CLEAR
	__inline void XRemoveMutuality(XGrid* pGrid, uint8 nPos)
	{
		uint8* const pCur = pGrid->pMutuality[nPos];
		for(int i = pGrid->nMutuality[nPos] - 1; i >= 0; --i)
		{
			uint8* const pTmp = pGrid->pMutuality[pCur[i]];
			const int  nTmp = --pGrid->nMutuality[pCur[i]];
			for(int j = 0; j < nTmp; ++j)
			{
				if(pTmp[j] == nPos)
				{
					for(int k = j; k < nTmp; ++k) pTmp[k] = pTmp[k+1];
					break;
				}
			}
		}
	}
#endif

// 加載測試數據
__inline int XLoadGrid(XGrid* pGrid, const char* pInput)
{
	int nPos = 0;

	int nMask = (1 << XGRID_BSIZE) - 1;

#ifdef XGRID_MUTUALITYSSE_CLEAR
	XMEMCOPY(pGrid->pMutuality, g_xMutuality, sizeof(g_xMutuality));
	XMEMCOPY(pGrid->nMutuality, g_nMutuality, sizeof(g_nMutuality));
#endif

	for(nPos = 0; nPos < XGRID_AREA; ++nPos) pGrid->xCells[nPos] = nMask;

	for(nPos = 0; nPos < XGRID_AREA; ++nPos)
	{
		if(pInput[nPos] >= '1' && pInput[nPos] <= '0' + XGRID_BSIZE)
		{	// 填充nPos的值為 1 << ( pInput[nPos] - '1' )
			if(XFillCellLoad(pGrid, pGrid->xCells, nPos, 1 << ( pInput[nPos] - '1' )) == XFILL_INVALID)
			{
				return XFILL_INVALID;
			} 
		}
	}

#ifdef XGRID_MUTUALITYSSE_CLEAR
	// [XGRID_BSIZE>=9且需要查找所有情況時清除關聯可加速]
	for(int i = 0; i < pGrid->nFilled; ++i)
	{
		XRemoveMutuality(pGrid, pGrid->pFilledPos[i]);
	}
#endif

	return XGRID_AREA - pGrid->nFilled;
}
 
__inline void XFillCellStack(XGrid* pGrid)
{
	__declspec(align(16)) XCells    xCellsStack[XGRID_AREA  + 1];
	__declspec(align(16)) int		nMinPosStack[XGRID_AREA];
	__declspec(align(16)) int		nCurValStack[XGRID_AREA];
	__declspec(align(16)) int		nFilledStack[XGRID_AREA];
	int nIndex = 0;

	XMEMCOPY(xCellsStack[0], pGrid->xCells, sizeof(xCellsStack[0]));

	// 查找當前填值可能性最少的單元格
	nMinPosStack[nIndex] = XFindMinFeasibilityPos(xCellsStack[nIndex]);
	nCurValStack[nIndex] = xCellsStack[nIndex][nMinPosStack[nIndex]];
	nFilledStack[nIndex] = pGrid->nFilled;

	while( (*pGrid->pRunMode & XRUN_FIND_FLAG) && nIndex >= 0 )
	{
		nFilledStack[nIndex + 1] = XFILL_INVALID;

		// 嘗試填充當前單元格
		while(nFilledStack[nIndex + 1] == XFILL_INVALID && nCurValStack[nIndex])
		{
			XMEMCOPY(xCellsStack[nIndex + 1], xCellsStack[nIndex], sizeof(xCellsStack[0]));
			unsigned int nMask = nCurValStack[nIndex] & -nCurValStack[nIndex];
			nCurValStack[nIndex] -= nMask;
			nFilledStack[nIndex + 1] = XFillCell(pGrid, xCellsStack[nIndex + 1], nMinPosStack[nIndex], nMask);
		}

		if(nFilledStack[nIndex + 1] > XGRID_AREA)
		{	// 沒有合法的填充值
			pGrid->nFilled = nFilledStack[--nIndex];
		}
		else if(nFilledStack[nIndex + 1] != XGRID_AREA)
		{	// 是合法的填充值, 還存在未填值的單元格
			++nIndex;
			// 查找當前填值可能性最少的單元格
			nMinPosStack[nIndex] = XFindMinFeasibilityPos(xCellsStack[nIndex]);
			nCurValStack[nIndex] = xCellsStack[nIndex][nMinPosStack[nIndex]];
		}
		else
		{	// 所有單元格均已填值
			XAddSolution(pGrid->pRunMode, pGrid->pTotal, xCellsStack[nIndex + 1]);
			pGrid->nFilled = nFilledStack[nIndex];
		}
	}
}


int	XFindGrid(int nRunMode, const char* pInput)
{
	int nTotal = 0;
	XGrid xGrid = {0};

	xGrid.pRunMode = &nRunMode;
	xGrid.pTotal   = &nTotal;

	// 加載網格數據
	switch(XLoadGrid(&xGrid, pInput))
	{
	case 0:
		nTotal = 1;
		break;
	case XFILL_INVALID:
		break;
	default:
		// 填充單元格
		XFillCellStack(&xGrid);
	}

	return nTotal;
}


/* 用TBB的Task模式對一個迷題的求解過程進行并行運算

class CXSudokuTask: public tbb::task 
{
	XGrid*	m_pGrid;
public:
	CXSudokuTask( XGrid* pGrid) : m_pGrid(pGrid){}

	tbb::task* execute() 
	{
		if( ( *m_pGrid->pRunMode & XRUN_FIND_FLAG ) == 0) return NULL;

		if( m_pGrid->nFilled < XGRID_CHANGE_MUTUALITY_SIZE) 
		{
			tbb::task_list list;

			__declspec(align(16)) XGrid  pChildGrid[XGRID_BSIZE];

			int nChildGrid = 0, nNewFilled = 0, nOldFilled = m_pGrid->nFilled;

			// 查找當前填值可能性最少的單元格
			int nMinPos = XFindMinFeasibilityPos(m_pGrid->xCells);

			// 如果當前單元格只有一種填值情況,則直接給該單元格填值
			if(g_xPopCnt[m_pGrid->xCells[nMinPos]] == 1 && nOldFilled < XGRID_AREA)
			{
				nNewFilled = XFillCell(m_pGrid, m_pGrid->xCells, nMinPos, m_pGrid->xCells[nMinPos]);
				nMinPos = XFindMinFeasibilityPos(m_pGrid->xCells);
			}

			if(nNewFilled < XGRID_AREA)
			{	// 存在多種可能的填值情況
				int  nCurVal = m_pGrid->xCells[nMinPos];

				while(nCurVal)
				{
					XGrid* pCurGrid = pChildGrid + nChildGrid;

					XMEMCOPY(pCurGrid, m_pGrid, sizeof(pChildGrid[0]));

					unsigned int nMask = nCurVal & -nCurVal;

					nCurVal -= nMask;

					// 給該單元格填可能的值
					nNewFilled = XFillCell(pCurGrid, pCurGrid->xCells, nMinPos, nMask);

					if(nNewFilled < XGRID_AREA) 
					{	// 是合法的填充值, 還存在未填值的單元格
#ifdef XGRID_MUTUALITYSSE_CLEAR
						// [XGRID_BSIZE>=9且需要查找所有情況時清除關聯可加速]
						for(int i = nOldFilled; i < nNewFilled; ++i)
						{
							XRemoveMutuality(pCurGrid, pCurGrid->pFilledPos[i]);
						}
#endif

						// 增加子Task
						list.push_back( *new( allocate_child() ) CXSudokuTask(pCurGrid));

						++nChildGrid;
					}
					else if(nNewFilled == XGRID_AREA)
					{	// 所有單元格均已填值
						XAddSolution(pCurGrid->pRunMode, pCurGrid->pTotal, pCurGrid->xCells);
					}
				}

				set_ref_count( nChildGrid + 1 );

				spawn_and_wait_for_all(list);
			}
			else if(nNewFilled == XGRID_AREA)
			{	// 所有單元格均已填值
				XAddSolution(m_pGrid->pRunMode, m_pGrid->pTotal, m_pGrid->xCells);
			}
		} 
		else
		{	
			XFillCellStack(m_pGrid); 
		}

		return NULL;
	}
};

// 大于 9 * 9 的網格 查找所有的填值可能方案時 效率更高 
void XParallelSudoku( XGrid* pGrid ) 
{
	CXSudokuTask& xTask = *new(tbb::task::allocate_root()) CXSudokuTask(pGrid);

	tbb::task::spawn_root_and_wait(xTask);
}
*/

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
一区二区久久久| 亚洲免费观看高清在线观看| 久久日一线二线三线suv| 亚洲婷婷在线视频| 精品一区二区三区香蕉蜜桃 | 在线观看视频一区二区| 精品国产乱码久久久久久蜜臀| 亚洲女同ⅹxx女同tv| 国精产品一区一区三区mba视频 | 亚洲一区二区三区爽爽爽爽爽| 欧美一级欧美一级在线播放| 国产精品网友自拍| 奇米色一区二区三区四区| 91久久精品网| 中文字幕免费一区| 久久99国内精品| 欧美影院一区二区三区| 中文字幕一区二区三区精华液| 91老师片黄在线观看| 欧美精品一区二区三区蜜桃 | 91精品福利视频| 欧美激情一区二区在线| 国产一区欧美二区| 精品捆绑美女sm三区| 丝袜亚洲另类欧美| 欧美精品亚洲一区二区在线播放| 亚洲欧美另类久久久精品| 日一区二区三区| 国产精品午夜电影| 欧美精品乱码久久久久久 | 日韩精品高清不卡| 欧美最猛黑人xxxxx猛交| 亚洲天堂精品在线观看| av亚洲精华国产精华精华| 欧美国产成人在线| 成人午夜精品在线| 国产精品每日更新| av在线这里只有精品| 成人免费在线视频观看| 91免费精品国自产拍在线不卡 | 精品欧美一区二区在线观看| 免费视频一区二区| 精品日韩一区二区| 国产精品资源网| 国产精品网站一区| 91丝袜高跟美女视频| 一区二区三区中文字幕电影| 国产精品福利电影一区二区三区四区| 精品国产一区二区精华| 麻豆久久一区二区| 久久久亚洲国产美女国产盗摄 | 亚洲少妇中出一区| 在线精品视频一区二区三四| 亚洲成av人片在www色猫咪| 欧美另类高清zo欧美| 久色婷婷小香蕉久久| 久久精品人人爽人人爽| 成人av网站免费观看| 亚洲线精品一区二区三区八戒| 欧美精品一二三区| 国产99精品在线观看| 亚洲精品美国一| 日韩欧美国产成人一区二区| 丰满亚洲少妇av| 亚洲成人黄色影院| 久久精品在线免费观看| 欧洲av一区二区嗯嗯嗯啊| 久久精品国产久精国产爱| 国产无遮挡一区二区三区毛片日本| 91视视频在线观看入口直接观看www | 久草热8精品视频在线观看| 国产精品少妇自拍| 51精品秘密在线观看| 成人午夜碰碰视频| 日韩—二三区免费观看av| 亚洲国产高清在线观看视频| 欧美日韩午夜精品| 成人黄色大片在线观看| 视频一区中文字幕| 日韩高清不卡在线| 中日韩av电影| 精品少妇一区二区三区| 日本高清成人免费播放| 国产酒店精品激情| 日韩经典中文字幕一区| 日韩毛片精品高清免费| 精品国产乱码久久久久久闺蜜| 色爱区综合激月婷婷| 国产精品一区在线| 日韩不卡一区二区三区 | 成人亚洲精品久久久久软件| 丝袜亚洲另类欧美| 亚洲婷婷国产精品电影人久久| 2021中文字幕一区亚洲| 欧美久久久久久久久久| 91久久香蕉国产日韩欧美9色| 国产酒店精品激情| 开心九九激情九九欧美日韩精美视频电影| 一区二区三区91| 国产精品久久久久毛片软件| 日韩精品一区二区三区swag| 欧美人牲a欧美精品| 一本久道久久综合中文字幕| 国产精品一区二区你懂的| 蜜桃精品视频在线| 水野朝阳av一区二区三区| 一区二区三区不卡在线观看| **欧美大码日韩| 国产清纯在线一区二区www| 精品福利视频一区二区三区| 日韩欧美国产综合在线一区二区三区| 欧洲一区在线观看| 欧美性xxxxxxxx| 欧美视频在线一区二区三区| 欧美三级电影在线看| 在线精品视频免费播放| 欧美日韩一区精品| 欧美精品久久一区二区三区| 91麻豆精品国产91久久久久| 91麻豆精品国产91| 精品少妇一区二区| xvideos.蜜桃一区二区| 国产日韩精品久久久| 国产精品无圣光一区二区| 最好看的中文字幕久久| 一区二区三区精品在线| 亚洲不卡av一区二区三区| 日韩一区精品字幕| 国内外成人在线视频| 成人一级片网址| 色综合久久久久综合99| 欧美色综合天天久久综合精品| 欧美日韩精品一区二区三区蜜桃| 91麻豆精品国产综合久久久久久 | 成人激情黄色小说| 亚洲欧洲三级电影| 日韩视频中午一区| 欧美色倩网站大全免费| 成人黄色网址在线观看| 久久66热re国产| 日韩av在线免费观看不卡| 一区二区在线电影| 国产精品久久久久影院亚瑟| 久久久精品天堂| 欧美一区二区三区婷婷月色| 欧美日韩国产123区| 91蜜桃在线免费视频| 大美女一区二区三区| 国产成人综合精品三级| 麻豆一区二区三| 美国毛片一区二区| 日本伊人色综合网| 日本亚洲天堂网| 国产精品无人区| 日本在线不卡视频一二三区| av不卡一区二区三区| 成人中文字幕在线| 大胆亚洲人体视频| 成人激情开心网| av一二三不卡影片| 色香色香欲天天天影视综合网| av在线播放成人| 色综合久久综合网97色综合 | 国产精品麻豆99久久久久久| 亚洲欧洲av在线| 亚洲同性gay激情无套| 亚洲精品乱码久久久久久| 有码一区二区三区| 天天综合日日夜夜精品| 蜜桃一区二区三区在线观看| 国产综合色视频| 成人国产在线观看| 色综合天天狠狠| 欧美区一区二区三区| 欧美成人vr18sexvr| 国产女同互慰高潮91漫画| 一区精品在线播放| 天天操天天综合网| 国产毛片精品一区| 99riav一区二区三区| 欧美老女人在线| 欧美精品一区二区在线播放| 国产精品丝袜久久久久久app| 亚洲精品自拍动漫在线| 青娱乐精品在线视频| 国产夫妻精品视频| 在线视频国内自拍亚洲视频| 欧美成人video| 最新国产精品久久精品| 日韩精品一区第一页| 岛国精品一区二区| 在线91免费看| 自拍偷在线精品自拍偷无码专区| 午夜激情久久久| 成人丝袜视频网| 欧美一区二区久久久| 亚洲日本中文字幕区| www.成人在线| 91精品国产综合久久久蜜臀图片| 亚洲国产精品成人综合色在线婷婷|