1. 程式人生 > >夜深人靜寫題解--牛客第六場

夜深人靜寫題解--牛客第六場

A  Garbage Classification

  模擬題

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3  
 4  
 5 int main()
 6 {
 7     int t;
 8     scanf("%d",&t);
 9     getchar();
10     for(int cases=1;cases<=t;cases++)
11     {
12         string str;
13         string s;
14         cin>>s>>str;
15         int d,w,h;
16         d=0;w=0;h=0;
17         for(int i=0;i<s.length();i++)
18         {
19             if(str[s[i]-'a']=='d')d++;
20             if(str[s[i]-'a']=='w')w++;
21             if(str[s[i]-'a']=='h')h++;
22         }
23         printf("Case #%d: ",cases);
24         if(h*4>=s.length())
25         {
26             puts("Harmful");
27         }
28         else if(h*10<=s.length())
29         {
30             puts("Recyclable");
31         }
32         else if(d>=w*2)
33         {
34             puts("Dry");
35         }
36         else puts("Wet");
37     }
38 }
View Code

B Shorten IPv6 Address

  大模擬題

  1 #include <iostream>
  2 #include <string.h>
  3 #include <stdio.h>
  4 #include <string>
  5 #include <stack>
  6 #include <queue>
  7 #include <algorithm>
  8 #include <math.h>
  9 #include <vector>
 10 #include <set>
 11 #define ll long long
 12 using namespace std;
 13 const int maxn = 1e6+7;
 14 ll mod   = 1e9+7;
 15 char a[130];
 16 int num[40];
 17 char b[17][10]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
 18 int judge(int local){
 19     int flag=1;
 20     for(int j=0;j<16;j++){
 21         flag=1;
 22         for(int i=local,k=0;k<4;k++,i++){
 23             if(b[j][k]!=a[i]){
 24                 flag=0;
 25                 break;
 26             }
 27         }
 28         if(flag) return j;
 29     }
 30     return 0;
 31 }
 32  
 33 int judgez(int local){
 34     for(int i=local;i<local+4;i++){
 35         if(num[i]!=0)
 36             return 0;
 37     }
 38     return 1;
 39 }
 40  
 41 int main()
 42 {
 43     int t;
 44     cin>>t;
 45     for(int cas=1;cas<=t;cas++){
 46         scanf("%s",a);
 47         int cnt=0;
 48         for(int i=0;i<128;i+=4){
 49             num[cnt++]=judge(i);
 50         }
 51         int maxx=2,tmp=0;
 52         int x=-1,y=-1;
 53         for(int i=0;i<32;i+=4){
 54             if(judgez(i)==1){
 55                 tmp++;
 56             }
 57             if(judgez(i)==0){
 58                 //printf("%d %d %d\n",i,tmp,maxx);
 59                 if(tmp>=maxx){
 60                     maxx=tmp;
 61                     y=i;
 62                     x=y-tmp*4;
 63                     y--;
 64                 }
 65                 tmp=0;
 66             }
 67             if(i==28&&tmp>=maxx){
 68                 maxx=tmp;
 69                 y=i+4;
 70                 x=y-tmp*4;
 71                 y--;
 72                 tmp=0;
 73             }
 74         }
 75         vector<pair<int,int> >front;
 76         vector<pair<int,int> >zhong;
 77         vector<pair<int,int> >back;
 78         tmp=0;
 79         for(int i=0;i<32;i+=4){
 80             if(judgez(i)==1){
 81                 tmp++;
 82             }
 83             if(judgez(i)==0){
 84                 //printf("%d %d %d\n",i,tmp,maxx);
 85                 if(tmp>=maxx){
 86                     y=i;
 87                     x=y-tmp*4;
 88                     y--;
 89                     //printf("maxx=%d\n",maxx);
 90                     if(x!=0&&y!=31)
 91                         zhong.push_back(make_pair(x,y));
 92                     if(x==0)
 93                         front.push_back(make_pair(x,y));
 94                     if(y==31)
 95                         back.push_back(make_pair(x,y));
 96                 }
 97                 tmp=0;
 98             }
 99             if(i==28&&tmp>=maxx){
100                 y=i+4;
101                 x=y-tmp*4;
102                 y--;
103                 //printf("maxx=%d\n",maxx);
104                 if(x==0)
105                     front.push_back(make_pair(x,y));
106                 if(x!=0&&y!=31)
107                     zhong.push_back(make_pair(x,y));
108                 if(y==31)
109                     back.push_back(make_pair(x,y));
110                 tmp=0;
111             }
112         }
113 //        printf("%d %d\n",x,y);
114         x=-1,y=-1;
115 //        /printf("%d %d %d\n",front.size(),zhong.size(),back.size());
116         if(zhong.size()!=0){
117             for(int i=0;i<zhong.size();i++){
118                 x=zhong[i].first;
119                 y=zhong[i].second;
120             }
121         }
122         else if(back.size()!=0){
123             x=back[0].first;
124             y=back[0].second;
125         }
126         else if(front.size()!=0){
127             x=front[0].first;
128             y=front[0].second;
129         }
130 //        printf("%d %d\n",x,y);
131         printf("Case #%d: ",cas);
132         cnt=0;
133 //        for(int i=0;i<32;i++) {
134 //            printf("%d",num[i]);
135 //            if(i%4==3)
136 //                printf(":");
137 //        }
138 //        printf("\n");
139         for(int i=0;i<32;i+=4){
140             if(i==x){
141                 printf("::");
142                 i=y-3;
143                 continue;
144             }
145             if(judgez(i)){
146                 printf("0");
147             }
148             else{
149                 int flag=0;
150                 for(int j=i;j<i+4;j++){
151                     if(num[j]) flag=1;
152                     if(flag==1) {
153                         if(num[j]>=10) printf("%c",'a'+num[j]-10);
154                         else printf("%d",num[j]);
155                     }
156                 }
157             }
158             //printf("   %d  &&\n",i);
159             if(i!=28&&i+4!=x)
160                 printf(":");
161         }
162         printf("\n");
163     }
164 }
View Code

D Move

  假二分題qaq

  題意:總共有n個物品需要裝進k個箱子裡,放箱子的策略為放盡可能能放進去的,也就是每次取最合適的放進去,直至放不了,問箱子的最少容量是多少

  思路:由於不滿足單調性,所以無法直接對箱子容積進行二分答案check,那麼就對於上下界進行討論,對於每個箱子最小容量至少為sum/k,最大體積為sum/k+max(v) ,暴力check,總複雜度為O(maxv*n*log(n));

  思路正確性:最小容量顯然滿足,最大容量,考慮到當前如果每個箱子都無法裝入某個物品,那麼對於對於每個箱子實際最大使用空間即為v-v1+1,v1為物品體積,v為箱子體積,則可以建立不等式

k*(v-v1+1)<sum,即v<sum/k+v1-1,限制該不等式主要為v1,將其設為最大值,則一定可以求得答案。

  程式碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+7;
 4 int a[maxn];
 5 multiset<int >mm;
 6 int main()
 7 {
 8     int t;
 9     scanf("%d",&t);
10     int temp=0;
11     while(t--)
12     {
13         int n,m;
14         temp++;
15         scanf("%d%d",&n,&m);
16         int sum=0;
17         int mxx=0;
18         for(int i=1; i<=n; i++)
19         {
20             scanf("%d",&a[i]);
21             mxx=max(a[i],mxx);
22             sum+=a[i];
23         }
24         int l,r;
25         r=0;
26         mm.clear();
27         for(int i=0;i<=mxx;i++){
28             mm.clear();
29             int mid=i+sum/m;
30             //printf("%d %d %d\n ",l,r,mid);
31             for(int i=1; i<=n; i++)
32             {
33                 mm.insert(a[i]);
34             }
35             int s=mid;
36             int jishu=0;
37             while(mm.size()>0)
38             {
39                // printf("%d\n",mm.size());
40                 auto ss=mm.upper_bound(s);
41                 if(ss==mm.begin())
42                 {
43                     s=mid;
44                     jishu++;
45                     continue;
46                 }
47                 ss--;
48                     s-=(*ss);
49                     mm.erase(ss);
50             }
51             if(s!=mid)
52             {
53                 jishu++;
54             }
55             //printf("%d\n",jishu);
56             if(jishu<=m)
57             {
58                 l=mid;
59                 break;
60             }
61         }
62         printf("Case #%d: %d\n",temp,l);
63     }
64 }
View Code 

J Upgrading Technology

  屬實自閉,賽後發現有個地方值初始化沒寫好qaq,交了25發。。

  題意:有n個人,可以升到m級,升級花費不同的價值,當所有人達到某一級時會獲得該等級的收入,花費有可能為負

  思路:對於每個等級進行暴力列舉,預處理1-m區間的字首花費,對預處理結果建立線段樹,儲存最小值,log(m)查詢區間最小值,當前等級一定會取到,主要是列舉後面是否能夠使當前花費最小,每個每個人花費最小得到的值,假如當前列舉到i等級,則求處i+1-m的最小值,與當前的值比較,若比當前值小則加入選擇的集合,注意的點是如果當前所有人的最小值都在後面,這樣就會直接導致等級被迫提升,所以我們要去掉一個值,以保證可以不得到後面的獎勵,去掉對當前答案影響最小的值,也就是min(sum)-sum[i]的最大值

  程式碼:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int inf=1e17+7;
  4 long long int  a[1500][1500];
  5 long long int sum[1500][1500];
  6 long long int d[1500];
  7    
  8 typedef struct node
  9 {
 10     int l,r;
 11     long long int minn;
 12 } Node;
 13 const int maxn = 1e3+7;
 14 Node tree[maxn][maxn<<2];
 15 void push_up(int i,int rt)
 16 {
 17     tree[i][rt].minn=min(tree[i][rt<<1].minn,tree[i][rt<<1|1].minn);
 18 }
 19 void build(int i,int rt,int l,int r)
 20 {
 21     tree[i][rt].l=l,tree[i][rt].r=r;
 22     if(l==r)
 23     {
 24         tree[i][rt].minn=sum[i][l];
 25         return ;
 26     }
 27     int mid = (l+r)/2;
 28     build(i,rt<<1,l,mid);
 29     build(i,rt<<1|1,mid+1,r);
 30     push_up(i,rt);
 31 }
 32 long long int query(int i,int rt,int l,int r)
 33 {
 34     if(r<l)return 1e15+7;
 35     //printf("%d %d\n",l,r);
 36     if(tree[i][rt].l>r||tree[i][rt].r<l)
 37     {
 38         return inf;
 39     }
 40     if(tree[i][rt].l>=l&&tree[i][rt].r<=r)
 41     {
 42         return tree[i][rt].minn;
 43     }
 44     int mid = (tree[i][rt].l+tree[i][rt].r)/2;
 45     long long int ans =1e17+7;;
 46     if(mid>=r)
 47     {
 48         ans=query(i,rt<<1,l,r);
 49     }
 50     else if(mid<l)
 51     {
 52         ans=query(i,rt<<1|1,l,r);
 53     }
 54     else
 55     {
 56         ans=min(query(i,rt<<1,l,mid),query(i,rt<<1|1,mid+1,r));
 57     }
 58     return ans;
 59 }
 60 int main()
 61 {
 62     int t;
 63     scanf("%d",&t);
 64     int temp=1;
 65     while(t--)
 66     {
 67         int n,m;
 68         scanf("%d%d",&n,&m);
 69         for(int i=1; i<=n; i++)
 70             for(int j=1; j<=m; j++)
 71                 scanf("%lld",&a[i][j]);
 72         for(int i=1; i<=m; i++)
 73         {
 74             scanf("%lld",&d[i]);
 75         }
 76         for(int i=1; i<=n; i++)
 77         {
 78             sum[i][0]=0;
 79             for(int j=1; j<=m; j++)
 80             {
 81                 sum[i][j]=sum[i][j-1]+a[i][j];
 82             }
 83         }
 84    
 85         for(int i=1; i<=n; i++)
 86             build(i,1,1,m);
 87    
 88         long long int ans=0;
 89         long long int qq=0;
 90         d[0]=0;
 91         for(int i=0; i<=m; i++)
 92         {
 93             qq+=d[i];
 94             long long int jishu=0;
 95             long long int se=0;
 96             int fi=0;
 97             int st=0;
 98             for(int j=1; j<=n; j++)
 99             {
100                 long long int mm=query(j,1,i+1,m);
101                 jishu+=min(mm,sum[j][i]);
102                 if(mm==1e15+7||mm>=sum[j][i])
103                 {
104                     fi=1;
105                 }
106                 else
107                 {
108                     if(st==0)
109                         se=mm-sum[j][i];
110                     else
111                     se=max(se,mm-sum[j][i]);
112                     st++;
113                 }
114                 //printf("+++   %lld %lld\n",mm,se);
115             }
116             if(fi==1)
117             {
118                 se=0;
119             }
120             ans=max(ans,qq-(jishu-se));
121             //printf("****%lld %lld\n",ans,jishu);
122         }
123         printf("Case #%d: %lld\n",temp++,ans);
124     }
125 }
View Code

&n