Codeforces Round 640 (Div. 4) 1
A. Sum of Round Numbers
考察拆位
对每一个数直接把每一个位置的数拆下来即可,采用边计算边处理的方式更加好
void solve()
{
cin>>n;
while(n--){
int x; cin>>x;
int now=1;
vector<int> ans;
while(x){
int y=x%10;
if(y){
ans.push_back(y*now);
}
x/=10;
now*=10;
}
cout<<ans.size()<<endl;
for(auto&v:ans) cout<<v<<' ';
cout<<endl;
}
return ;
}
B. Same Parity Summands
考察奇偶处理
如果能拆成m个偶数一每一个偶数都>=2,奇数则是>=1所以只要前面都是2看最后一个是不是偶数,奇数同理
void solve()
{
cin>>n>>m;
if(n>=m*2 && (n-(m-1)*2)%2==0){
cout<<"YES"<<endl;
for(int i=1;i<=m-1;i++) cout<<2<<' ';
cout<<n-(m-1)*2<<endl;
return ;
}
if(n>=m && (n-(m-1))&1){
cout<<"YES"<<endl;
for(int i=1;i<=m-1;i++) cout<<1<<' ';
cout<<n-(m-1)<<endl;
return ;
}
cout<<"NO"<<endl;
return ;
}
C. K-th Not Divisible by n
考察除法和模数
我们简单模拟可以发现每次倍数之能增加的都是n-1,则我们需要看有几个n-1在里面如果恰好是整数倍的话需要-1
void solve()
{
cin>>n>>m;
int x=m/(n-1),y=m%(n-1);
if(!y){
cout<<x*n-1<<endl;
}
else{
cout<<x*n+y<<endl;
}
return ;
}
D - Alice, Bob and Candies
考察基础双指针
我们直接按照题目意思使用双指针模拟就好用,while写法会更加简洁
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i];
int tim=0,a=0,b=0,lasta=0,lastb=0;
int l=1,r=n;
while(l<=r){
tim++;
while(l<=r && lasta<=lastb){
a+=w[l];
lasta+=w[l];
l++;
}
if(l>r) break;
lastb=0;
tim++;
while(l<=r && lastb<=lasta){
b+=w[r];
lastb+=w[r];
r--;
}
lasta=0;
}
cout<<tim<<' '<<a<<' '<<b<<endl;
return ;
}
E. Special Elements
前缀和和数据范围的处理
注意到内存很小我们能不用map就不用,考虑范围很小使用n2的前缀和来处理,注意每一次清空的只要是到n即可
bitset<N> ton;
int a[N],b[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=b[i-1]+a[i];
}
for(int i=1;i<=n;i++) ton[i]=0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
if(b[j]-b[i-1]<=n){
ton[b[j]-b[i-1]]=true;
}
}
int ans=0;
for(int i=1;i<=n;i++)
if(ton[a[i]]) ans++;
cout<<ans<<endl;
return ;
}
F. Binary String Reconstruction
简单构造
依照题目意思一定是有解的我们不妨先处理11和00,然后对10和01做分类讨论即可
// 模拟题细心研究细节
void solve()
{
int a,b,c; cin>>a>>b>>c;
if(c){// 构造 11
for(int i=1;i<=c+1;i++) cout<<1;
}
if(a){// 构造00
for(int i=1;i<=a+1;i++) cout<<0;
}
if(b){// 表示10的数量1100
if(c&&a){// 11100 我只要加一个就是1 就是加一接着加0 就是加一
int cnt=1;
while(cnt<b){
cout<<1;
cnt++;
if(cnt==b) break;
cout<<0;
cnt++;
}
}
else if(c){
int cnt=0;
while(cnt<b){// 111
cout<<0;
cnt++;
if(cnt==b) break;
cout<<1;
cnt++;
}
}
else if(a){// 00
int cnt=0;
while(cnt<b){// 11100
cout<<1;
cnt++;
if(cnt==b) break;
cout<<0;
cnt++;
}
}
else{
int cnt=-1;
while(cnt<b){// 11100
cout<<1;
cnt++;
if(cnt==b) break;
cout<<0;
cnt++;
}
}
}
cout<<endl;
return ;
}
PS:简单写法
void solve()
{
int a,b,c; cin>>a>>b>>c;
string s;
for(int i=1;i<=a+1;i++) s+='0';// 一定会有一个0
if(b==0&&c==0){
cout<<s<<endl;
return ;
}
int cnt=b;
if(b==0) s.clear();
c++;
while(c--) s+='1';
cnt--;
if(cnt<=0){
cout<<s<<endl;
return ;
}
while(cnt){
s+="0";
cnt--;
if(!cnt) break;
s+='1';
cnt--;
}
cout<<s<<endl;
return ;
}
G. Special Permutation
简单构造
首先手动模拟发现<=3不可以
我们直观的想法有直接按照由外向内的排列方式这样每个数都会隔开2,
但是对于中间位置我们却不好处理,会应为数变化但是我们钥匙从大到小
的从外到内来排序会发现中间的位置一定是2和1处于矛盾之中我们直接
交换2,4问题就迎刃而解
int a[N];
void solve()
{
cin>>n;
if(n<=3){
cout<<-1<<endl;
return ;
}
int l=1,r=n;
int now=n;
while(l<=r){
a[l++]=now--;
if(l>r) break;
a[r--]=now--;
}
for(int i=1;i<=n;i++){
if(a[i]==2) cout<<4<<' ';
else if(a[i]==4) cout<<2<<' ';
else cout<<a[i]<<' ';
}
cout<<endl;
return ;
}