A. Print a Pedestal (Codeforces logo?)
分析
一个数n,h1,h2,h3满足h1+h2+h3=n;h1>h2>h3。找出最小的h1。
判断n是否能被3整除,将数字分为三份,之后再对其进行添加或删减,使h1最小时满足题意。
代码
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define guanliu ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const ll maxn=2e5+10;
const ll mod=1e9+7;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int main()
{
guanliu;
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int a,b,c;
if(n%3==0)
{
b=n/3;
a=b+1;
c=b-1;
}
else if(n%3==1)
{
b=n/3;
a=b+2;
c=b-1;
}
else {
b=n/3;
a=b+2;
c=b-1;
b++;
}
cout<<b<<" "<<a<<" "<<c<<endl;
}
return 0;
}
B. Array Decrements
分析
a,b两个数组,a数组可以每个数进行每次-1操作,当a数组变为0时,不能再减了,判断是否可以通过操作后,将a数组变为b数组。
如果两个数组之间每位的差都相同,就可以,但是要考虑b数组出现0的情况,出现0这位需要a的值比差小,这样才能保证本位减为0。特别考虑全为0的情况
代码
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define guanliu ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const ll maxn=5e4+10;
const ll mod=1e9+7;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int a[maxn],b[maxn];
int main()
{
guanliu;
int t;
cin>>t;
while(t--)
{
int f=1;
int c=INF;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
cin>>b[i];
}
for(int i=1;i<=n;i++)
{
if(b[i]!=0)
{
c=a[i]-b[i];
continue;
}
}
if(c<0)
{
cout<<"NO"<<endl;
continue;
}
if(c==INF)
{
cout<<"YES"<<endl;
continue;
}
for(int i=1;i<=n;i++)
{
if(b[i]==0)
{
if(a[i]<=c) continue;
}
if(a[i]-b[i]!=c)
{
f=0;
break;
}
}
if(f==1) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
C. Restoring the Duration of Tasks
分析
给出每个程序的到达时间和结束时间,输出每个程序进行了多久。每个程序必须进行完当前的程序,才能进行下一个。
判断一下到达时间和结束时间是否重合,如果不重合,进行时间就是结束时间减到达时间,如果重合,必须执行完当前的才能执行下一个,所以当前先不执行,它要从上一个结束之后开始执行,运行时间就是结束时间减上一个结束时间。
ps:这里数据保证了没有程序覆盖情况,即当前程序还没结束,下一个程序到来,并且比当前程序还早结束的情况。所以不用考虑这种情况!
代码
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define guanliu ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const ll maxn=2e5+10;
const ll mod=1e9+7;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int s[maxn],f[maxn],d[maxn];
int main()
{
guanliu;
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i];
}
for(int i=1;i<=n;i++)
{
cin>>f[i];
}
d[1]=f[1]-s[1];
for(int i=2;i<=n;i++)
{
if(f[i-1]<=s[i])
{
d[i]=f[i]-s[i];
}
else {
d[i]=f[i]-f[i-1];
}
}
for(int i=1;i<=n;i++)
{
cout<<d[i]<<" ";
}
cout<<endl;
}
return 0;
}
D. Black and White Stripe
分析
一个BW串,B代表黑色,W代表白色,将最少的W变成B,使能有k个B相连。
本来以为动态规划(但是不会、、、)发现不需要,只需要将所有的W进行一个前缀和统计,枚举每个k个区间的W的数量(这里用到了前缀和)然后求一个min就好了。就是暴力求解,前缀和优化W的数量。
代码
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define guanliu ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const ll maxn=2e5+10;
const ll mod=1e9+7;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int a[maxn],b[maxn];
int main()
{
guanliu;
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
string s;
cin>>s;
for(int i=0;i<n;i++)
{
if(s[i]=='W') b[i]=1;
else b[i]=0;
}
if(b[0]==1)
{
a[0]=1;
}
else a[0]=0;
for(int i=0;i<n;i++) //前缀和
{
if(b[i]==1)
{
a[i]=a[i-1]+1;
}
else a[i]=a[i-1];
}
int ans=a[k-1];
for(int i=k;i<n;i++)
{
ans=min(a[i]-a[i-k],ans);
}
cout<<ans<<endl;
}
return 0;
}
E. Price Maximization
分析
n个数,选两个数相加后除k,商值相加,最后使这个和最大。
先对每个数求对k的商相加,再将每个数修改为k的余数(只有商最后对答案有影响,余数可能会相加后再对k求商,之后再对答案有影响)。使和最大,先排序,用最小和最大加,如果最小和最大加仍无法对答案有贡献,那么这个数没有办法对答案有贡献,双指针遍历一遍,求出最后答案。
注意:需要开ll!
代码
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define guanliu ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const ll maxn=2e5+10;
const ll mod=1e9+7;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
ll a[maxn];
int main()
{
guanliu;
int t;
cin>>t;
while(t--)
{
ll n,k;
cin>>n>>k;
ll cnt=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>=k)
{
cnt+=a[i]/k;
a[i]%=k;
}
}
sort(a+1,a+n+1);
ll l=1,r=n;
while(l<r)
{
if(a[l]+a[r]>=k)
{
cnt++;
l++;
r--;
}
else l++;
}
cout<<cnt<<endl;
}
return 0;
}