kickstart-E
A题 简答模拟题
1 #include <iostream> 2 #include<stdio.h> 3 #include <set> 4 #include <algorithm> 5 #include <vector> 6 #include <string> 7 #include <cstring> 8 using namespace std; 9 int a[5002],b[5002]; 10 11 int main() 12 { 13 freopen("/Users/zjg/CLionProjects/ac/A-large-practice.in","r",stdin); 14 freopen("/Users/zjg/CLionProjects/ac/A-large-practice.out","w",stdout); 15 int TT; 16 cin>>TT; 17 for(int t=1;t<=TT;t++) 18 { 19 memset(a,0,sizeof(a)); 20 memset(b,0,sizeof(b)); 21 vector<int> v; 22 int n,k; 23 cin>>n>>k; 24 for(int i=0;i<n;i++) 25 cin>>a[i]; 26 sort(a,a+n); 27 int T=0; 28 for(int i=0;i<n;i++) 29 { 30 if(i==0) 31 { 32 b[T]++; 33 v.push_back(a[i]); 34 } 35 else if(a[i]==a[i-1])b[T]++; 36 else if(a[i]!=a[i-1]) 37 { 38 b[++T]++; 39 v.push_back(a[i]); 40 } 41 } 42 long long num=0; 43 long long ans=0; 44 45 for(int i=v[T];i>0;i--) 46 { 47 if(T>=0&&i==v[T]) 48 num+=b[T--]; 49 ans+=num<k?num:k; 50 if(num>k)num-=k; 51 else num=0; 52 } 53 cout<<"Case #"<<t<<": "<<ans<<endl; 54 } 55 return 0; 56 }
B题
正解是按照bit构造。因为只有M个constraint,所以只要找到complaint最小的前M+1个二进制数,一定有一个是符合条件的。假设s[0,...,p+1]位于前M+1个,那么s[0,..,p]一定也是前M+1个。Proof by contradiction: 如果s[0,...,p+1](表示长度为p+1)是前M+1个而s[0,...,p]不是,假设s[p+1]增加的complaint是x,那么排在s[0,...,p]之前的s'[0,...,p]增加一个相同的bit (s[p+1]),构成的新的二进制数的complaint一定比s[0,...,p+1]小,如此可以产生多于M+1个complaint比s[0,..,p+1]小的二进制数,和s[p+1]位于前M+1矛盾。
Then 如果s[0,...,p]不是前M+1个,s[0,..,p+1]一定也不是前M+1个,无论新增的bit是0 or 1.所以对于每个bit p,维护前M个s[0,..,p],对下一个bit增加0 or 1,再对bit p+1排序找出前M+1个……
可以预处理求出N个二进制数bit p的1的个数之和,这样从bit p to bit p+1可以O(1)求出新增的complaint。
1 #include <string> 2 #include <vector> 3 #include<iostream> 4 #include<cstdio> 5 #include<queue> 6 #include<cmath> 7 #include <set> 8 #include<algorithm> 9 #include<cstring> 10 11 using namespace std; 12 13 int main(){ 14 freopen("/Users/zjg/CLionProjects/ac/B-large-practice.in","r",stdin); 15 freopen("/Users/zjg/CLionProjects/ac/B-large-practice.out","w",stdout); 16 int kase; 17 cin>>kase; 18 for(int k=0;k<kase;k++){ 19 int n,m,p; 20 cin>>n>>m>>p; 21 vector<int> cnt(p); 22 for(int i=0;i<n;i++){ 23 string s; 24 cin>>s; 25 for(int j=0;j<p;j++)if(s[j]=='1') ++cnt[j]; 26 } 27 vector<string> ban(m); 28 for(int i=0;i<m;i++) cin>>ban[i]; 29 priority_queue<pair<int,string>> que; que.emplace(0,""); 30 for(int i=0;i<p;i++){ 31 int a=cnt[i]; 32 int b=n-a; 33 auto tmp=que; 34 while(que.size()) que.pop(); 35 while(tmp.size()){ 36 int t; 37 string s; 38 tie(t,s)=tmp.top(); tmp.pop(); 39 que.emplace(t+a,s+"0"); 40 que.emplace(t+b,s+"1"); 41 while(que.size()>101) que.pop(); 42 } 43 } 44 int re; 45 set<string> st(ban.begin(),ban.end()); 46 while(que.size()){ 47 int t; 48 string s; 49 tie(t,s)=que.top(); que.pop(); 50 if(st.count(s)) continue; 51 re=t; 52 } 53 cout<<"Case #"<<k+1<<": "<<re<<endl; 54 } 55 return 0; 56 }