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