昨天也是有幸能够参加这场比赛,也是成功被军训了,d题难度真是比以往的d题的难度上升了不少水平,完全没有做出来,我以为就是一个dp就行,但是想了20分钟依旧没想出来,但是看到别的大犇的写法,才发现,何止一个dp,还需要一个差分,等我学会别的大犇的做法,再来更新我这个篇博客好了
A. Split the Multiset
题意:就是说给你一个n和k,初始时集合只有一个n元素,然后最多可以将集合里的数拆成k个元素,还要确保k个元素之和为原本的数
思路:纯水题一个,要不是一开始网站炸了,两分钟就能a掉这道题,仔细看数据,其实就是将一开始的n拆分成n个1需要几步,每次拆分最多可以出现(k-1)个1,然后我们再对(n-1)%(k-1)是否等于0分情况讨论即可,然后就是注意k是否等于1,等于1,直接输出1,即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
signed main()
{
cin>>t;
while(t--)
{
cin>>n>>k;
if(k==1)
{
cout<<1<<"\n";
continue;
}
else
{
if((n-1)%(k-1)==0)
{
cout<<(n-1)/(k-1)<<"\n";
}
else
{
cout<<(n-1)/(k-1)+1<<"\n";
}
}
}
return 0;
}
B. Make Majority
题意:就是说给你一串01序列,然后有一种判断准则,你可以选择一个区间,如果区间的0的个数>=1的个数,那么整个区间融合就是0,反之,融合则是1
思路:我们完全可以将01序列里面的所有连续的0变成一个0,然后最后统计0的个数和1的个数,最后判断,如果1的个数大于0,则输出YES,如果1的个数小于等于0的个数,那么就是NO
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n;
string s;
int a[200005];
signed main()
{
cin>>t;
while(t--)
{
int cnt0=0,cnt1=0;
cin>>n;
cin>>s;
int flag=1;
for(int i=0;i<s.size();i++)
{
if(s[i]=='1')
{
a[i+1]=1;
cnt1++;
}
else
{
a[i+1]=0;
}
}
for(int i=1;i<=n;i++)
{
if(flag==1&&a[i]==0)
{
cnt0++;
flag=0;
}
if(flag==0&&a[i]==1)
{
flag=1;
}
}
if(cnt1>cnt0)
{
cout<<"YES\n";
}
else
{
cout<<"NO\n";
}
}
return 0;
}
C. Increasing Sequence with Fixed OR
题意:就是说给你一个数n,要你构造一个序列,序列的要求为前后两个数的或要等于n
思路:妥妥的构造题,其实构造题在平常比赛中是一种较难的题型,我们需要先来观察这个构造序列,我们发现构造的序列的最后一个数一定是n这个数,我们会发现如果将其n展开为二进制序列,我们会发现一个有趣的规律,如果我们二进制序列只有一个1,那么我们序列的长度就为1,并且要输出其本身,如果有2个及以上,那么序列最长可以有(1+二进制序列中1的个数)个数字(这个是用来判断序列的长度的)
接下来我们考虑如何构造,我们去观察最后两个数据
先来看14,这个数据二进制表示 14(1110),12(1100),10(1010),4 (0100),这个你发现了什么,你是不是发现,倒数第二个数和倒数第三个数,都是在最后一个数的基础上各自消失了一个1,然后我们的然后第一个数,是在第三个数的基础上消失了1位1,那么我们就可以知道,第i个数和i+2个数有关系
反之再测试23依然可以得证这个关系,因此可以知道这个关系是正确的
然后就可以写出代码了
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n;
int fast(int a, int b)
{
long long result = 1;
long long base = a;
while (b > 0)
{
if (b % 2 == 1)
{
result = (result * base) ;
}
base = (base * base) ;
b /= 2;
}
return result;
}
signed main()
{
cin>>t;
while(t--)
{
int a[63];
int len=0;
cin>>n;
int sum=n;
while(sum>0)
{
len++;
a[len]=sum%2;
sum/=2;
}
int cnt=0;
for(int i=len;i>0;i--)
{
if(a[i]==1)
{
cnt++;
}
}
if(cnt==1)
{
cout<<cnt<<"\n";
cout<<n<<"\n";
continue;
}
cout<<cnt+1<<"\n";
int ans[cnt+2];
ans[cnt+1]=n;
int z1,z2;
int flag=cnt;
for(int i=0;i<len;i++)
{
if(((n>>i)&1)==1&&(flag==cnt||flag==cnt-1))
{
ans[flag]=n-fast(2,i);
flag--;
continue;
}
if(((n>>i)&1)==1&&flag<cnt-1)
{
ans[flag]=ans[flag+2]-fast(2,i);
flag--;
continue;
}
}
for(int i=1;i<=cnt+1;i++)
{
cout<<ans[i]<<" ";
}
cout<<"\n";
}
return 0;
}