LeetCode Hard 選做


題目鏈接


感受一下自己能不能切lc的hard題(退役后這么閑的怕是就我一個)。
hard間難度差異很大,有的巨水像easy,所以可能會挑着做。
基本都是DP/數學/計算幾何,我這種主做數據結構的怎么辦


做了十幾道Hard,沒想到LeetCode Hard題比我想象的還要簡單。。而且感覺連題意都不會描述(更不要說數據范圍),放NOIP普及組都能被沖爆。
最近許多比賽的Hard也依然很水(\(\approx\)牛客小白月賽的難題),真hard的應該很少很少。
(它這周賽隨便找個OIer/ACMer都能出)

總之,Hard難度區間大概在 我高中學OI 半個月到八九個月左右 的水平。

不想做了太無聊了。做算法入門題還行,但大廠算法面試就這?這也叫算法?絕了。


4. 尋找兩個正序數組的中位數

/*
easy題。
log做法的話,因為目標是找合並后第k大的值,設兩個數組為v1,v2,假設第k大在第一個數組的v1[p]位置,那么對第二個數組的k-p位置,應有v1[p]>=v2[k-p-1],否則v1取的元素不夠,p需右移。
p移動是單調的,所以可以二分。
*/
#include <bits/stdc++.h>
using namespace std;

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=1e5+5;

	int A[N];

	double findMedianSortedArrays(vector<int>& v1, vector<int>& v2)
	{
		std::vector<int> vec;
		auto it1=v1.begin(),it2=v2.begin();
		while(it1!=v1.end() || it2!=v2.end())
		{
			if(it1==v1.end()||(it2!=v2.end()&&*it1>*it2)) vec.pb(*it2++);
			else vec.pb(*it1++);
		}
		for(auto v:vec) printf("%d ",v); pc('\n');
		int n=vec.size()-1;
		return (vec[n/2]+vec[n/2+(n&1)])/2.0;
	}
};
Solution sol;

int main()
{

	return 0;
}

10. 正則表達式匹配

/*
入門DP。555人有點凌亂寫得很亂。
f[i][j]表示s的前i個字符是否能和p的前j個字符匹配,分情況討論、轉移即可。
*/
#include <bits/stdc++.h>
using namespace std;

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=55;

	int f[N][N];

	bool isMatch(string s, string p)
	{
		int n=s.length(),m=p.length();
		s.insert(0,1,'@'), p.insert(0,"@");

		f[0][0]=1;
		for(int j=2; j<=m; j+=2)
			if(p[j]=='*') f[0][j]=1;
			else break;
		for(int i=1; i<=n; ++i)
			for(int j=1; j<=m; ++j)
			{
				if(p[j]=='*')
				{
					if(f[i][j-2]||f[i][j-1]) f[i][j]=1;
					if(f[i-1][j] && (s[i]==p[j-1]||p[j-1]=='.')) f[i][j]=1;
				}
				else if(f[i-1][j-1]&&(s[i]==p[j]||p[j]=='.')) f[i][j]=1;
				if(f[i][j] && j+2<=m && p[j+2]=='*') f[i][j+2]=1;
			}
//		for(int i=1; i<=n; ++i)
//			for(int j=1; j<=m; ++j)
//				printf("f[%d][%d]=%d\n",i,j,f[i][j]);
		return f[n][m];
	}
};
Solution sol;

int main()
{
	string a,b; cin>>a>>b;
	printf("%d\n",sol.isMatch(a,b));

	return 0;
}

23. 合並K個升序鏈表

/*
最簡單做法也是easy。做這種題有點使我變傻,真的去想一個個合並了(而且沒怎么用過指針555)。
用堆把鏈表里所有元素push進去,依次取建鏈表即可。用原有元素就行,不需要new。
因為list有序,所以不需將所有元素push,每次push當前list最前面那個即可,每次取再push。這樣就是O(log總鏈表數)而不是O(log總元素數)。
得到鏈表的簡單方式是,建一個head和*tail=&head,元素依次放入tail->next,然后更新tail=tail->next,最后返回head.next即可。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=1e5+5;

	struct Node
	{
		int val;
		ListNode *ptr;
		bool operator <(const Node &x)const
		{
			return val>x.val;
		}
	};
	std::priority_queue<Node> q;

	ListNode* mergeKLists(vector<ListNode*>& ls)
	{
		for(auto v:ls) if(v) q.push(Node{v->val,v});//注意判v!=NULL!

		ListNode head, *tail=&head;
		while(!q.empty())
		{
			Node x=q.top(); q.pop();
			tail = tail->next = x.ptr;
			if(x.ptr->next) q.push(Node{x.ptr->next->val, x.ptr->next});
		}
		return head.next;
	}
};
Solution sol;

int main()
{
//	sol.Main();

	return 0;
}

25. K 個一組翻轉鏈表

/*
easy題。十來分鍾過了,感覺做了一個題指針鏈表已經完全會了.jpg。
就把鏈表每k個倒序存一遍(將next賦值為它原本的pre)。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=1e5+5;

//	struct ListNode
//	{
//		int val;
//		ListNode *next;
//		ListNode(): val(0), next(nullptr) {}
//		ListNode(int x): val(x), next(nullptr) {}
//		ListNode(int x, ListNode *next): val(x), next(next) {}
//	};

	ListNode* reverseKGroup(ListNode* head, int k)
	{
		ListNode ans, *anst=&ans, *t=NULL, *tmp=NULL, *nxt=NULL;

		int cnt=0;
		while(head)
		{
			nxt = head->next;
			if(!t) t=head, t->next=NULL;
			else tmp=t, t=head, t->next=tmp;
			
			head = nxt;
			if(++cnt==k)
			{
				while(t)
					anst = anst->next = t, t = t->next;
				t=NULL, cnt=0;
			}
		}
		head=t, t=NULL;//剩下的部分已經反轉了,再反轉一遍即可。
		while(head)
		{
			nxt = head->next;
			if(!t) t=head, t->next=NULL;
			else tmp=t, t=head, t->next=tmp;
			
			head = nxt;
			if(!head)
				while(t)
					anst = anst->next = t, t = t->next;
		}
		return ans.next;
	}
};
Solution sol;

int main()
{
//	sol.Main();

	return 0;
}

30. 串聯所有單詞的子串

/*
...這可能算middle題?
假設有n個單詞,每個單詞長為k,總長m=nk,那么位置p合法即s[p,p+m)能匹配n個單詞。 
Sol 1.
因為單詞互不相同,枚舉每個長為m的區間,再對其中每個長為k的區間找出其對應的單詞,看最后是否能對應所有n個單詞。
用unordered_map找對應單詞,復雜度是$O(|s|*m)$。如果用Trie找對應單詞是O(|s|*m*k)。
最大復雜度實際是$O((|s|-m)*m)=O(\frac{|s|^2}{4})$,所以很容易過。
Sol 2.
在做法1中,對很多長為k的區間,我們會重復為它找對應單詞多次,事實上只需要一次。
從s的0到k-1位置分別開始,依次對每個長為k的區間,找到它的對應單詞,並保存已找到的單詞數。
當處理了n個長為k的區間時,看下現在已找到所有n個單詞,然后將最早的那個區間的找到的單詞刪掉,再處理下個長為k的區間即可。
用unordered_map找對應單詞,復雜度$O(|s|*k)$。$k$只有30所以非常低。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=5005;

	int cnt[N],CNT[N],ID[N<<1];
	std::unordered_map<std::string, int> mp;

	vector<int> findSubstring(string s, vector<string>& words)
	{
		int L=s.length(), n=words.size(), k=words[0].length(), m=n*k, t=0;
		for(auto v:words)
		{
			if(!mp.count(v)) mp[v]=++t;
			++CNT[mp[v]];
		}
		
		std::vector<int> res;
		for(int p=0; p<k; ++p)
		{
			cnt[0]=1e9;
			int tot=0, delta=0;
			for(int i=p; i+k<=L; i+=k)//i+k可等於k!
			{
				int id=mp[s.substr(i,k)];
				ID[i]=id;
				if(++cnt[id]<=CNT[id])
					if(++tot==n) res.emplace_back(p+delta);
				if(i+k-p-delta==m)
				{
					id=ID[p+delta];
					if(--cnt[id]<CNT[id]) --tot;
					delta+=k;
				}
			}
			memset(cnt, 0, t+1<<2);
		}
		return res;
	}
};
Solution sol;

int main()
{

	return 0;
}

32. 最長有效括號

/*
算middle?
最簡單的想法,依次枚舉字符,遇到'('就++top,遇到')',若top!=0,就--top,++cnt(當前右括號數),否則令cnt=0(右括號更多了,不合法)。
然后考慮什么時候可用cnt更新答案:因為會有左括號更多的不合法情況,此時不能確定是否更新答案,所以只能在--top后,top==0時更新答案ans=max(ans, cnt*2)。
但這樣計算不了左括號數>右括號數的序列的貢獻,所以將串反轉、'('')'互換后,再做一遍取max即可。
這樣空間是O(1)的。

還有個簡單做法,將匹配上的左右括號縮成一個字符比如'1',然后統計最后序列最長連續'1'的個數。
因為縮兩個字符不方便,所以令匹配上的'('=' ',')'='1',最后' '不影響連續性。

還有種好寫的方法是,用棧push所有左括號位置,匹配到右括號就取一下 當前位置-上次未匹配位置(就是棧頂,初始為-1)。
當左括號少於右括號時,清空棧,將棧頂初始值設為當前右括號位置。看代碼吧。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=3e4+5;
	
//	int sk[N];

	int Calc(string s,const char ch)
	{
		int top=0,ans=0,cnt=0;
		for(auto c:s)
			if(c==ch) ++top;
			else if(top) --top, ++cnt, !top&&(ans=std::max(ans, cnt*2));
			else cnt=0;
		cout<<s<<'\n'<<ans<<'\n';
		return ans;
	}
	int longestValidParentheses(string s)
	{
		int tmp=Calc(s,'(');
		std::reverse(s.begin(), s.end());//s=string(s.rbegin(),s.rend())
		return std::max(tmp,Calc(s,')'));

//		int top=0,ans=0,l=s.length();
//Sol 2.
//		for(int i=0; i<l; ++i)
//		{
//			if(s[i]=='(') sk[++top]=i;
//			else if(top) s[i]='1', s[sk[top--]]=' ';
//		}
//		for(int i=0,now=0; i<l; ++i)
//			if(s[i]=='('||s[i]==')') now=0;
//			else if(s[i]=='1') ans=std::max(ans, ++now);
//		return ans*2;
//Sol 3.
//		sk[top=1]=-1;
//		for(int i=0; i<l; ++i)
//			if(s[i]=='(') sk[++top]=i;
//			else //')'
//				if(!--top) sk[top=1]=i;//右括號更多 
//				else ans=std::max(ans, i-sk[top]);
//		return ans;
	}
};
Solution sol;

int main()
{
	string s; cin>>s;
	printf("%d\n",sol.longestValidParentheses(s));

	return 0;
}

37. 解數獨

/*
。。DFS入門題,算easy題吧。
搞不懂為什么要bitset,用結構體存9個數的bool,枚舉的時候同時看看行、列、所屬塊的該數bool值就行了,常數是27;用bitset或一遍得到可填數后也仍要枚舉9次,且也要常數9^2/w,bitset有啥用啊。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	#define ID(x,y) ((x-1)/3*3+(y+2)/3)
	typedef long long LL;
	const static int N=90;

	struct Node
	{
		int x,y;
	}pos[N];
	struct Status
	{
		bool A[9];
	}row[10],col[10],block[10];

	inline void Fill(int x,int y,int num)
	{
		row[x].A[num]=1, col[y].A[num]=1, block[ID(x,y)].A[num]=1;
	}
	inline void Unfill(int x,int y,int num)
	{
		row[x].A[num]=0, col[y].A[num]=0, block[ID(x,y)].A[num]=0;
	}
	bool DFS(int n,vector<vector<char>>& board)
	{
		if(!n) return 1;
		int x=pos[n].x, y=pos[n].y; --n;
		Status &r=row[x], &c=col[y], &b=block[ID(x,y)];
		for(int i=8; ~i; --i)
			if(!r.A[i] && !c.A[i] && !b.A[i])
			{
				Fill(x,y,i);
				if(DFS(n,board)) return board[x-1][y-1]=i+49, 1;
				Unfill(x,y,i);
			}
		return 0;
	}
	void solveSudoku(vector<vector<char>>& board)
	{
		int n=0;
		for(int i=1; i<=9; ++i)
		{
			int j=1;
			for(auto c:board[i-1])
			{
				if(c=='.') pos[++n]={i,j};
				else Fill(i,j,c-'1');
				++j;
			}
		}
		DFS(n,board);
	}
};
Solution sol;

int main()
{
//	sol.Main();

	return 0;
}

41. 缺失的第一個正數

/*
限制時間O(n)、常數級復雜度有點難,有點想不到(事實上就沒見過這種O(n)讀入還不讓開O(n)空間的),算hard吧?(但感覺完全是個trick)
設數組長為n,則只需一個大小為n的數組表示[1,n]中每個數是否出現過。
因為不能開這個數組,所以考慮將給的輸入數組改為那個數組,來標記[1,n]中哪些數出現過。
有兩種方法:
1. 直接修改原數組會丟失原有的值,但我們只關心[1,n]這些值,其它無關值(不在[1,n]內)都可設成任意一個數(如n+1)。
注意這樣就可將所有數化為正數,然后在每個數前加負號,是不會丟失原有值的。所以我們用正負號做bool值:x\in [1,n]出現過,就令vec[x-1]變為負(vec為給定數組)(注意不是乘-1,因為x可出現多次)。
這個 為不影響原數組值 且不開新數組,將 正負號 作為 bool值 的思路真是沒見過。
2. 若vec[x-1]\in [1,n] 且 vec[x-1]!=x,則令vec[x-1]與vec[vec[x-1]-1]交換,直到vec[x-1]\notin [1,n] 或 vec[x-1]==x。
可以發現最終,若x\in [1,n] 且 x出現過,則一定有vec[x-1]=x。且一個位置最多被交換一次,所以均攤復雜度也是O(n)。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=1e5+5;

	int firstMissingPositive(vector<int>& nums)
	{
		#define V 2000000000
		int n=nums.size();
		for(auto &v:nums)
			if(v>n || v<=0) v=V;
		for(auto v:nums)
			if(std::abs(v)<=n) nums[std::abs(v)-1]=-std::abs(nums[std::abs(v)-1]); // 注意v和nums[v-1]均取abs!
		int i=0;
		for(auto v:nums)
			if(++i, v>0) return i;
		return n+1;
	}
};
Solution sol;

int main()
{
	vector<int> v; int x;
	while(~scanf("%d",&x)) v.pb(x);
	printf("%d\n",sol.firstMissingPositive(v));

	return 0;
}

42. 接雨水

/*
middle題吧,雖然也easy。
就拿個棧存高度、位置,每次pop掉前面高度小於等於自己的,然后用他們間的距離*前面那個位置的高度差算貢獻。
發現算不了2 0 1這種左邊更高的情況,將序列反轉再求一遍即可(注意此時不能pop前面高度等於自己的,會重復)。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=3e4+5;

	struct Node
	{
		int p,h;
	}sk[N];

	int trap(vector<int>& ht)
	{
		int n=ht.size(),ans=0,top=0,i=0;
		sk[0]={0,(int)1e9};
		for(auto h:ht)
		{
			++i;
			for(int las=0; h>=sk[top].h; --top)
				ans+=(sk[top].h-las)*(i-sk[top].p-1), las=sk[top].h;
			sk[++top]={i,h};
		}
		
		std::reverse(ht.begin(),ht.end());
		sk[0]={0,(int)1e9};
		for(auto h:ht)
		{
			++i;
			for(int las=0; h>sk[top].h; --top)
				ans+=(sk[top].h-las)*(i-sk[top].p-1), las=sk[top].h;
			sk[++top]={i,h};
		}

		return ans;
	}
};
Solution sol;

int main()
{
	vector<int> v; int x;
	while(~scanf("%d",&x)) v.pb(x);
	sol.trap(v);

	return 0;
}



381. O(1) 時間插入、刪除和獲取隨機元素 - 允許重復

/*
這種沒見過誒。。
因為要隨機獲取元素,所以基本只能是將所有數存在一個vector中。插入可直接在vector末尾插入。
直接在vector里刪除是O(n)的。注意vector中數是無序的,刪除一個數可以將它交換到vector尾部,然后pop_back,O(1)刪除。
這樣還需要對每個數,維護它出現的下標位置,且要能O(1)動態查找、插入、刪除值,只能用unordered_set(同樣也是Hash實現,也有unordered_multiset)。

因為vector也可以存迭代器,所以可不用下標,將unordered_map<int, unordered_set<int>>換成unordered_multimap<int, int>,vector<int>換成vector<unordered_multimap<int, int>::iterator>。
具體細節相同。這樣減少了一次哈希,常數小很多。

這題竟然是通過足夠多次getRandom()判答案,hhhnb,怪不得測這么慢。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class RandomizedCollection
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	typedef long long LL;
	const static int N=1e5+5;

	std::vector<int> all;
	std::unordered_map<int, std::unordered_set<int>> mp;
//	std::unordered_multimap<int, int> mp;
//	vector<std::unordered_multimap<int, int>::iterator> all;

	RandomizedCollection() {}
	bool insert(int val)
	{
		bool ret=mp[val].empty();
		mp[val].insert(all.size()), all.pb(val);
		return ret;
	}
	bool remove(int val)
	{
		if(mp[val].empty()) return 0;

		auto it=mp[val].begin();//unordered_set沒有rbegin 
		int pos=*it; mp[val].erase(it);
		
		int v2=*all.rbegin();
		all[pos]=v2, mp[v2].insert(pos);//先insert再erase,val==v2且val在末尾時先erase可能erase不到元素。
		all.pop_back(), mp[v2].erase(all.size());

		return 1;
	}
	int getRandom()
	{
		return all[rand()%all.size()];
	}
};
RandomizedCollection sol;

int main()
{
//	vector<int> v; int x;
//	while(~scanf("%d",&x)) v.pb(x);
	printf("%d\n",sol.insert(1));
	printf("%d\n",sol.remove(1));
	printf("%d\n",sol.insert(1));

	return 0;
}

1931. 用三種不同顏色為網格塗色

前面題太無聊了看看后面的(近期比賽的hard題)
雖然也很無聊

/*
無聊的入門狀壓。。3^m狀壓每列顏色。基數是3比較麻煩(取模常數比較大),但是弄成4也麻煩,所以對每個狀態預處理一下染色情況。
然后O(243*243*m)預處理下哪兩個狀態間可以轉移,這樣DP的時候就可以少一個m倍常數。
另外因為m只有5,如果很閑所有的狀態間的轉移 是可以手推出來的(也可以寫個正常DP然后打表出有用的轉移,當然純屬無聊)。
*/
#include <bits/stdc++.h>
#define gc() getchar()
using namespace std;

inline int read()
{
	int now=0,f=1; char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}

class Solution
{
public:
	#define pc putchar
	#define gc() getchar()
	#define pb emplace_back
	#define mod 1000000007
	#define Mod(x) x>=mod&&(x-=mod)
	typedef long long LL;
	const static int N=1e3+5,M=27*9+5;//M=243

	int f[N][M],sta[M][5],S[M],ok[M][M];

	int colorTheGrid(int m, int n)
	{
		int lim=1,cnt=0; for(int t=m; t--; lim*=3);
		for(int ss=0; ss<lim; ++ss)
		{
			int las=-1,fg=1;
			for(int i=0,s=ss,x; i<m; ++i)
				x=s%3, s/=3, fg=fg&(las!=x), sta[ss][i]=las=x;
			if(fg) S[++cnt]=ss, f[1][cnt]=1;
		}

		for(int i=1; i<=cnt; ++i)
			for(int j=i+1; j<=cnt; ++j)
			{
				int s=S[i],s2=S[j],fg=1;
				for(int k=0; k<m; ++k)
					if(sta[s][k]==sta[s2][k]) fg=0;
				fg && (ok[i][j]=ok[j][i]=1);
			}

		for(int i=1; i<n; ++i)
			for(int j=1,v; j<=cnt; ++j)
				if((v=f[i][j]))
					for(int k=1; k<=cnt; ++k)
						if(ok[j][k]) f[i+1][k]+=v, Mod(f[i+1][k]);

		LL res=0;
		for(int i=1; i<=cnt; ++i) res+=f[n][i];
		return res%mod;
	}
};
Solution sol;

int main()
{
//	vector<int> v; int x;
//	while(~scanf("%d",&x)) v.pb(x);
	printf("%d\n",sol.colorTheGrid(read(),read()));

	return 0;
}

1938. 查詢最大基因差

??這都什么無聊的題,模板套模板就是能出一場比賽的hard?題目描述也很含糊,我見過的出題人都沒這么寫題意的。
這題就 在線 樹剖+可持久化Trie(這種是顯然,別的解法沒想),離線 DFS+Trie。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM