Codeforces Round #608 Div. 2
链接https://codeforces.com/contest/1271
A. Suits
题意:两种方式搭配衬衫。a、d 价值 e元,b、c、d价值 f 元。问最大的价值
思路:e、f 哪个大先配哪个
#include <bits/stdc++.h>
#define fi first
#define se second
#define ll long long
using namespace std;
const int maxn=1000+5,maxm=1e5+5;
const int mod=1e9+7,inf=0x7f7f7f7f;
ll a,b,c,d,e,f;
int main()
{
cin>>a>>b>>c>>d>>e>>f;
ll ans=0;
if(e>=f)
{
ll t=min(a,d);
ans+=t*e;
d-=t;
ll z=min(b,c);
z=min(z,d);
ans+=z*f;
}
else
{
ll t=min(b,c);
t=min(t,d);
ans+=t*f;
d-=t;
ans+=min(a,d)*e;
}
cout<<ans<<"\n";
return 0;
}
B. Blocks(模拟)
题意:给定WBWBWB这样的字符串,可以选择一个位置,同时翻转两个字符的颜色。要使得字符串最后全为同一种颜色。请你输出:翻转的方案
思路:明明可以
O
(
n
)
O(n)
O(n) 做。结果自己一直想着把 B 都移到一起,把 W 都移到一起,结果输出就超过 3n了
#include <bits/stdc++.h>
#define fi first
#define se second
#define ll long long
using namespace std;
const int maxn=200+5,maxm=1e5+5;
const int mod=1e9+7,inf=0x7f7f7f7f;
int n;
string s;
int main()
{
cin>>n>>s;
int cnt0=0,cnt1=0;
for(int i=0;i<n;++i)
if(s[i]=='B') cnt0++;
else cnt1++;
if(cnt0%2==1&&cnt1%2==1)
{
puts("-1");
return 0;
}
vector<int> ans;
if(cnt0%2==0)
{
for(int i=0;i<n-1;++i)
{
if(s[i]=='B'&&s[i+1]=='W')
swap(s[i],s[i+1]),ans.push_back(i+1),i--;
if(s[i]=='B'&&s[i+1]=='B')
ans.push_back(i+1),i++;
}
}
else if(cnt1%2==0)
{
for(int i=0;i<n-1;++i)
{
if(s[i]=='W'&&s[i+1]=='B')
swap(s[i],s[i+1]),ans.push_back(i+1),i--;
if(s[i]=='W'&&s[i+1]=='W')
ans.push_back(i+1),i++;
}
}
cout<<(int)ans.size()<<"\n";
for(auto i : ans)
cout<<i<<" ";
puts("");
return 0;
}
C. Shawarma Tent(模拟)
题意:在学校周围建一个营地使得经过这个营地的人数最多。
思路:8个方向统计一下人数即可
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int nn,x,y;
int a,b,c,d,n,s,w,e;
int main()
{
cin>>nn>>x>>y;
for(int i=1;i<=nn;++i)
{
int nx,ny;
scanf("%d%d",&nx,&ny);
if(nx==x&&ny>y) n++;
else if(nx==x&&ny<y) s++;
else if(ny==y&&nx>x) e++;
else if(ny==y&&nx<x) w++;
else if(nx<x&&ny>y) a++;
else if(nx<x&&ny<y) d++;
else if(nx>x&&ny>y) b++;
else if(nx>x&&ny<y) c++;
}
int ans1=a+b+n,ans2=b+c+e;
int ans3=d+c+s,ans4=a+d+w;
int maxx1=max(ans1,ans2);
int maxx2=max(ans3,ans4);
int maxx=max(maxx1,maxx2);
if(maxx==ans1) y++;
else if(maxx==ans2) x++;
else if(maxx==ans3) y--;
else if(maxx==ans4) x--;
cout<<maxx<<"\n";
cout<<x<<" "<<y<<"\n";
return 0;
}
E. Common Number(思维)
题意:根据函数,[1,n]每个数都有一条路径。问经过至少 k 次的最大值是多少
思路:根据 奇偶是可以得到当前某个数 x 到 n 的节点数的。复杂度 log n 。可以直接二分奇数和偶数取最大值
直接从高位异或得到答案
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,k;
ll check(ll x)
{
int p=(x&1?0:1);
ll cnt=0;
while(x<=n)
{
cnt+=min(n-x+1,(1ll<<p));
p++;
x*=2;
}
return cnt;
}
int main()
{
cin>>n>>k;
ll ans=0;
for(int i=62;i>=0;--i)
{
ans|=(1ll<<i);
if(check(ans)<k)
ans^=(1ll<<i);
}
cout<<ans<<"\n";
return 0;
}
分别二分奇数和偶数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,k;
ll check(ll x)
{
int p=(x&1?0:1);
ll cnt=0;
while(x<=n)
{
cnt+=min(n-x+1,(1ll<<p));
p++;
x*=2;
}
return cnt;
}
int main()
{
cin>>n>>k;
ll l=0,r=n/2;
while(l<r)
{
ll mid=(l+r+1)>>1;
if(check(2*mid)>=k)
l=mid;
else
r=mid-1;
}
ll ans=2*l;
l=0,r=(n+1)/2;
while(l<r)
{
ll mid=(l+r+1)>>1;
if(check(2*mid+1)>=k)
l=mid;
else
r=mid-1;
}
ans=max(ans,2*l+1);
cout<<ans<<"\n";
return 0;
}