1. 程式人生 > >[USACO]高低卡(金)High Card Low Card (Gold)

[USACO]高低卡(金)High Card Low Card (Gold)

有 2N 張牌,它們的點數分別為 1 到 2N 。Bessie 拿了其中的 N 張,Elsie 拿了剩下的 N 張。
Bessie 和 Elsie 會進行 K 輪遊戲,在每輪遊戲中,Bessie 和 Elsie 各出一張牌。出了的牌不能收回。
在前 N/2 輪中,誰的牌點數大誰就贏;在後 N/2 輪中,誰的牌點數小誰就贏。
已知 Elsie 每一輪會出什麼牌,試求 Bessie 最多能贏多少輪。 2≤N≤50000, 保證 N 是偶數。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=5e4+7;
 8 int a[maxn],b[maxn];
 9 int n,tp,ans,l,r,mid;
10 bool vis[maxn],usd[maxn];
11 int main(){
12   cin>>n;
13 for(int i=1;i<=n;i++) {cin>>a[i];vis[a[i]]=true;} 14 for(int i=1;i<=2*n;i++){ 15 if(!vis[i]) b[++tp]=i; 16 } 17 for(int i=1;i<=n/2;i++){ 18 l=n/2+1;r=n; 19 while(l<=r){ 20 mid=(l+r)/2;while(usd[mid]&&mid<=n) mid++; 21 while(usd[mid]&&mid>=1
) mid--; 22 if(b[mid]>a[i]) r=mid-1; 23 else l=mid+1; 24 } 25 if(b[l]>a[i]) {usd[l]=true;ans++;} 26 } 27 for(int i=n/2+1;i<=n;i++){ 28 l=1;r=n/2; 29 while(l<=r){ 30 mid=(l+r)/2;while(usd[mid]&&mid<=n) mid++; 31 while(usd[mid]&&mid>=1) mid--; 32 if(b[mid]<a[i]) r=mid-1; 33 else l=mid+1; 34 } 35 if(b[l]<a[i]) {usd[l]=true;ans++;} 36 } 37 cout<<ans<<endl; 38 }
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn=5e6+7;
 7 int a[maxn],b[maxn],bel[maxn];
 8 int n,atp,btp,ans;
 9 int main(){
10   cin>>n;
11   for(int i=1;i<=n/2;i++){
12     cin>>a[i];bel[a[i]]=1;
13   }
14   for(int i=1;i<=n/2;i++){
15     cin>>b[i];bel[b[i]]=1;
16   }
17   sort(a+1,a+n/2+1);atp=n/2;
18   sort(b+1,b+n/2+1);btp=n/2;
19   int j=2*n;
20   for(int i=n/2;i>=1;i--){
21     while(bel[j]&&j>=1) j--;
22     if(j<a[i]) continue;//????????
23     else bel[j]=1,ans++;
24   }
25   j=1;
26   for(int i=1;i<=n/2;i++){
27     while(bel[j]&&j<=2*n) j++;
28     if(j>b[i]) continue;//????????
29     else bel[j]=1,ans++;
30   }
31   cout<<ans<<endl;
32   return 0;
33 }