A. Print a Pedestal (Codeforces logo?)
题意:将一个数n分成三部分,中间最大,第二大是左边,最小是右边,详见代码
C++代码:
#include<iostream>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int k=n%3;
if(k==0){
cout<<n/3<<" "<<n/3+1<<' '<<n/3-1<<endl;
}else if(k==1){
cout<<n/3<<' '<<n/3+2<<' '<<n/3-1<<endl;
}else{
cout<<n/3+1<<' '<<n/3+2<<' '<<n/3-1<<endl;
}
}
}
B. Array Decrements
题意:给定两个数组a,b,每次可以对数组a进行如下操作:将a的每个数减一(0减去1还是0);求a是否能通过该操作变成b(没有操作次数的限制)
C++代码如下:
#include<iostream>
using namespace std;
const int N=50010;
int a[N],b[N];
int main(){
int t;
cin>>t;
while(t--){
int n,maxx=0,flag=0;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int j=1;j<=n;j++){
cin>>b[j];
maxx=max(maxx,a[j]-b[j]);//求a[i]-b[i]最大的差
}
for(int i=1;i<=n;i++){
if(b[i]==0&&a[i]-b[i]<=maxx&&a[i]-b[i]>=0)continue;
else if(b[i]!=0&&a[i]-b[i]==maxx)continue;
else{
flag=1;
break;
}
}
if(flag)puts("NO");
else puts("YES");
}
return 0;
}
C. Restoring the Duration of Tasks
题意:求出每个任务运行的时间,详见代码
C++代码如下:
#include<iostream>
using namespace std;
const int N=200010;
int s[N],f[N];
int main(){
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];
for(int i=1;i<=n;i++)cout<<f[i]-max(s[i],f[i-1])<<" ";
cout<<endl;
}
return 0;
}
D. Black and White Stripe
题意:给定一个只包含‘W’和'B'的字符串s,找出一个长度为k的子串,使得将它全部变成'B'所需要改变的’W'最少
1、设置一个数组cnt[],cnt[i]记录s[i]及其之前所出现的’W'的个数,cnt[i]=cnt[i-1]+(s[i]=='W')
2、遍历字符串s,同时更新cnt,当i>=k时,更新答案minn=min(minn,cnt[i]-cnt[i-k])
cnt[i]-cnt[i-k]即为s中下标为i-k+1~i的长度为k的子串中'W'的个数
C++代码如下:
#include<iostream>
using namespace std;
const int N=200010;
int cnt[N];//cnt[i]记录s[i]及其之前所出现过的'W'的个数
int main(){
int t;
cin>>t;
while(t--){
int n,k,minn=1e9;//minn记录最少需要将几个白色变成黑色
cin>>n>>k;
for(int i=0;i<=n;i++)cnt[i]=0;
string s;
cin>>s;
s=' '+s;
for(int i=1;i<s.size();i++){
cnt[i]=cnt[i-1]+(s[i]=='W');
if(i>=k)minn=min(minn,cnt[i]-cnt[i-k]);//如果i>=k,则更新minn
}
cout<<minn<<endl;
}
return 0;
}
E. Price Maximization
题意:将一个有n个数(n为偶数)的数组a[]分成n/2份,每份两个数,求(每一份的和/k)加起来的最大值,变量sum记录答案,初始化为0
1、输入数组时边做:sum+=a[i]/k,a[i]%=k,然后数组a每个数都存的是对k的余数
2、对数组a进行从大到小排序
3、i=1,j=n,双指针判断两个数能否结合成一组,如果a[i]+a[j]>=n,则表示可以结合,此时i++,j--,sum++(sum只加一因为a[i]+a[j]一定小于2*n),如果不能结合,j就往前移(不把i往后移是因为a[i+1]+a[j]<=a[i]+a[j],即更不可能结合),直到i和j相遇
C++代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
int a[N];
bool cmp(int a,int b){
return a>b;
}
int main(){
int t;
cin>>t;
while(t--){
int n,k;
long long sum=0;//记得开long long,不然会爆int
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i]/k;
a[i]%=k;
}
sort(a+1,a+n+1,cmp);
int i=1,j=n;
while(i<j){//双指针进行匹配
if((a[i]+a[j])/k)i++,j--,sum++;
else j--;
}
cout<<sum<<endl;
}
return 0;
}
剩下两题不T_T