2017年湖南省第十三屆大學生計算機程式設計競賽-D Tian Ji's Horse Race Again
阿新 • • 發佈:2019-02-08
思路:貪心。對於King的馬a[n]和Tian的馬b[n],交換的k匹馬,肯定是取a[n]的最大值和b[n]的最小值交換,那麼對於a[],b[]的比較排列是固定的,因此主要怎麼求贏得次數,由於a,b都是由小到大排序的,因此可以先求出對於b[i]至少要交換多少匹馬才能夠使得b[i]贏,這樣就可以把所有情況都先預處理好。
Code :
#include<iostream> #include<algorithm> #include<map> using namespace std; const int MAX_N=100005; int n,Q; int a[MAX_N],b[MAX_N]; int ans[MAX_N]; int main() { while(~scanf("%d%d",&n,&Q)){ for(int i=n-1;i>=0;--i) scanf("%d",&a[i]); for(int i=0;i<n;++i) scanf("%d",&b[i]); map<int,int> imap; for(int i=n-1,k=0;i>=0;--i) { while(k<n&&a[k]<b[i]){ ++k; } //對於b[i]至少要向右移多少個才能贏(不把右移的交換的情況下,即a[]不變) int t=max(0,n-k-i); ++imap[t]; ans[i]=0; } int m=0,sum=0; for(auto c:imap) { sum+=c.second; //由於右移後的b[i]會到a[]去,因此只需要(c.first+1)/2就能夠贏 m=(c.first+1)/2; ans[m]=sum; } for(int i=1;i<=n;++i) if(!ans[i]) ans[i]=ans[i-1]; while(Q--){ scanf("%d",&sum); int res=n; if(sum<=m) res=min(res,ans[sum]); printf("%d\n",res); } } return 0; }