[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 }

猜你喜欢

转载自www.cnblogs.com/lcan/p/9820442.html
今日推荐