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 }

 

posted @ 2018-10-20 00:59  demianzhang  阅读(188)  评论(0编辑  收藏  举报