题目链接
A
思路
贪心,因为只有一个共享的,所以钱多的先使用
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include<bits/stdc++.h> using namespace std; int main() { long long a,b,c,d,e,f; cin>>a>>b>>c>>d>>e>>f; long long ans = 0; if(e>f){ ans+=min(a,d)*e; d-=min(a,d); ans+=min(d,min(b,c))*f; } else { ans+=min(d,min(b,c))*f; d-=min(d,min(b,c)); ans+=min(a,d)*e; } cout<<ans<<endl; }
|
B
思路
观察到每次都可以让两个相同的变换,但是如果是奇数的话就不可能,所以判断白色块和黑色块的奇偶性,然后偶数块数的就可以变为相反的,每次选取两端的,然后利用前缀和数组来维护,最后我们去除无用的操作即可。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include<bits/stdc++.h> using namespace std; #define ll long long int a[800]; int pre[800]; int ji,ou; vector<int>j; vector<int>o; vector<int>v; int main() { int n; scanf("%d",&n); string s; int ans = 0; cin>>s; for(int i=0;i<n;i++) { if(s[i]=='B')o.push_back(i+1),ou++; else j.push_back(i+1),ji++; } if(ji%2==1&&ou%2==1)return 0*printf("-1\n"); else { if(ji%2==0) { for(int i=0;i<j.size()/2;i++) { pre[j[i]]=1; pre[j[i+j.size()/2]]=-1; } } else { for(int i=0;i<o.size()/2;i++) { pre[o[i]]=1; pre[o[i+o.size()/2]]=-1; } } } for(int i=1;i<=n;i++)pre[i]+=pre[i-1]; for(int i=1;i<=n;i++) { pre[i]%=2; ans+=(pre[i]==1); } printf("%d\n",ans); for(int i=1;i<=n;i++)if(pre[i]==1)printf("%d ",i); }
|
C
思路
很简单的一道题,建立的tent在学校的四周的最靠近点上的时候都可以,只有四种情况,然后考虑不同的情况即可
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include<bits/stdc++.h> using namespace std; #define ll long long int up,leftt,rightt,down; int main() { int n,sx,sy; cin>>n>>sx>>sy; for(int i=0;i<n;i++) { int x,y; scanf("%d %d",&x,&y); if(x<sx)leftt++; else if(x>sx)rightt++; if(y<sy)down++; else if(y>sy)up++; } if(up>=down&&up>=leftt&&up>=rightt)printf("%d\n%d %d",up,sx,sy+1); else if(down>=up&&down>=leftt&&down>=rightt)printf("%d\n%d %d",down,sx,sy-1); else if(leftt>=up&&leftt>=rightt&&leftt>=down)printf("%d\n%d %d",leftt ,sx-1,sy); else printf("%d\n%d %d",rightt,sx+1,sy); }
|
D
留坑
E
来填坑了,
思路
分奇数偶数,假设x为奇数,那么能到达它的数有2x,2x+1,2x+2,2x+3,然后在推一次4x,4x+1,…,4x+7,偶数的话就先+1到奇数然后这样就可以了。
这样我们就能在$log_2n$复杂度之内求出一个数的Path了,然后再考虑求最大的答案,首先证明单调性,分奇数偶数,小的奇数肯定比大的奇数的path值要大因为我们再上面证明了小的奇数可以由大的奇数推出来,因此我们就可以使用二分的方式求出答案。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include<bits/stdc++.h> using namespace std; #define ll long long ll k,n; ll calji(ll x) { ll ans = 0; ll res = 1; while(x<=k) { ans+=res; x=2*x+1; res*=2; } x-=res-1; if(k>=x) ans+=(k-x+1); return ans; } ll calou(ll x) { if(x==k)return 1; if(x==k+1)return 2; ll ans = 0; ll res = 2; x=x+1; while(x<=k) { ans+=res; x*=2; x+=1; res*=2; } x-=res-1; if(k>=x)ans+=(k-x+1); return ans; } int main() { scanf("%lld %lld",&k,&n); ll l = 1,r=k; ll jians = l; while(l<r) { ll mid = (l+r)>>1; if(mid%2==0)mid++; ll num = calji(mid); if(num>=n) { l=mid+1; jians = mid; } else r=mid-1; } ll left=1,right=k,ouans=left; while(left<right) { ll mid = (left+right)>>1; if(mid%2==1)mid++; ll num = calou(mid); if(num >=n ){ left = mid +1; ouans=mid; } else right = mid - 1; } printf("%lld\n",max(jians,ouans)); }
|