2020-05-18 — 习题训练一
A - Phoenix and Balance
将一堆质量为2,4,8,,,2^n的硬币,分为数量相同,质量尽可能接近的两组,
2+4+8+...+2^n-1 小于 2^n(差了2),质量大的要跟质量小的在一起,所以质量差(2+2^2...2^(n/2-1))*2+2
#include<iostream> using namespace std; typedef long long ll; #define ture true #define flase false int a[100010]; int main( ) { int k,n; cin>>k; while(k--){ cin>>n; n=n/2; ll sum=0; ll a=2; while(n--){ sum+=a; a*=2; } cout<<sum<<endl; } return 0; }
B - Phoenix and Beauty
n个数,要求插入一些数,使连续的m个数和都相等,就得m个一循环,
设一共有k种数字,k>m,就不能好好循环了,k不到m个填充一些数字变成m个再循环,循环n次就肯定可以变成原来的数列啦
#include<cmath> #include<cstdio> #include<algorithm> #include<string> #include<vector> #include<iomanip> #include<iostream> using namespace std; typedef long long ll; #define ture true #define flase false int main( ) { int t; int n,k,i,sum,z; cin>>t; while(t--) { int a[10010]={0},b[10010]={0}; cin>>n>>k; sum=0; for(i=0; i<n; i++) { cin>>z; if(a[z]==0) { a[z]=1; b[sum++]=z; } } if(sum>k) { cout<<-1<<endl;; } else { cout<<n*k<<endl; for(i=sum; i<k; i++) { b[i]=1; } for(i=0; i<n; i++) { for(int j=0; j<k; j++) { cout<<b[j]<<" "; } } cout<<endl; } } return 0; }
C - Road To Zero
给两个数n,m,花费a使期中一个数-1,花费b使两个都-1,求让nm都减到0最少需要花费多少,
如果2*a<b,一个一个减就好了,如果a*2>b,min(x,y)*b+abs(x-y)*a
#include<cmath> #include<cstdio> #include<algorithm> #include<string> #include<vector> #include<iomanip> #include<iostream> using namespace std; typedef long long ll; #define ture true #define flase false int a[100010]; int main( ) { ll k,n,m,a,b,x,y; ll sum; cin>>k; while(k--){ cin>>x>>y; cin>>a>>b; if(a*2<=b){ sum=(x+y)*a; cout<<sum<<endl; }else{ sum=min(x,y)*b+abs(x-y)*a; cout<<sum<<endl; } } return 0; }
D - Binary Period
给一个字符串,只含有01,插入一些字符,使得周期最小
如果字符串中只有一种数字,就直接输出原来的字符串,周期为1
否则就输出字符串长度个数的01,周期为2最小
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<string>
#include<vector>
#include<iomanip>
#include<iostream>
using namespace std;
typedef long long ll;
#define ture true
#define flase false
int a[100010];
int main( )
{
int k;
int n,a,b,c,d,i;
cin>>k;
while(k--){
string s;
cin>>s;
int flag =0;
for(i=1;i<s.length();i++){
if(s[i]!=s[i-1]){
flag=1;
break;
}
}
if(flag==0)
{
cout<<s<<endl;
}
else
{
for(i=0; i<s.length(); i++)
{
cout<<"01";
}
cout<<endl;
}
}
return 0;
}
E - Nastya and Rice
b个再[a-b,a+b]范围内的数,总和在[c-d,c+d],问给定的数能否满足这个条件
即满足(a-b)*n<(c+d)和(a+b)*n>(c-d)
#include<cmath> #include<cstdio> #include<algorithm> #include<string> #include<vector> #include<iomanip> #include<iostream> using namespace std; typedef long long ll; #define ture true #define flase false int a[100010]; int main( ) { int k; int n,a,b,c,d; cin>>k; while(k--){ cin>>n>>a>>b>>c>>d; if((a-b)*n>(c+d)||(a+b)*n<(c-d)){ cout<<"NO"<<endl; }else{ cout<<"YES"<<endl; } } return 0; }
F - Nastya and Door
一个巨大的门,掉到山峰(比左边右边都高)上就跌成两半,给定门的长度和一串山脉,问最多能跌成几块
是前缀和!循环一圈找最大的数量
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<string>
#include<vector>
#include<iomanip>
#include<iostream>
using namespace std;
typedef long long ll;
#define ture true
#define flase false
int main( )
{
int t;
int n,k,i,sum,a[200100];
cin>>t;
while(t--)
{
int b[200100]={0};
cin>>n>>k;
for(i=1;i<=n;i++){
cin>>a[i];
}
for(i=2;i<n;i++){
if(a[i]>a[i-1]&&a[i]>a[i+1]){
b[i]=b[i-1]+1;
}else{
b[i]=b[i-1];
}
}
int max=0,num,flag;
for(i=1;i<=n-k+1;i++){
num=b[i+k-2]-b[i]+1;
if(num>max) max=num,flag=i;
}
cout<<max<<" "<<flag<<endl;
}
return 0;
}

浙公网安备 33010602011771号