爆0的一场,寄寄寄。
A
\(n\)一开始肯定分成\(k\)份,每一份最多增加\(k-1\)。模拟计算即可。
#include <bits/stdc++.h> #define lowbit(x) x&(-x) const int MAXN=2e5+10; const int mod=998244353; using namespace std; using ll=long long; void solve(); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t=1; cin>>t; while(t--) { solve(); } } void solve() { int n,k; cin>>n>>k; if(n==1) { cout<<0<<"\n"; return; } int ans=1; int sum=k; while(sum<n) { sum+=(k-1); ans++; } cout<<ans<<"\n"; }
|
B
考虑少了一种情况:11在串中出现两次也是合法。
方法一:分类讨论直接写。
#include <bits/stdc++.h> #define lowbit(x) x&(-x) const int MAXN=2e5+10; const int mod=998244353; using namespace std; using ll=long long; void solve(); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t=1; cin>>t; while(t--) { solve(); } } void solve() { int n; cin>>n; string s; cin>>s; if(n==1) { if(s=="1") cout<<"YES\n"; else cout<<"NO\n"; return; } if(s[0]=='0' && s[n-1]=='0') { int cnt=0; int cnt_1=1; int maxn=0; for(int i=0;i<n-1;i++) { if(s[i]==s[i+1] && s[i]=='1') { cnt_1++; } else { if(cnt_1>1) { cnt++; } maxn=max(cnt_1,maxn); cnt_1=1; } } if(maxn>2 || cnt>1) cout<<"YES\n"; else cout<<"NO\n"; } else if(s[0]=='1' && s[n-1]=='1') { cout<<"YES\n"; } else if(s[0]=='0' && s[n-1]=='1') { for(int i=0;i<n-1;i++) { if(s[i+1]==s[i] && s[i]=='1') { cout<<"YES\n"; return; } } cout<<"NO\n"; } else if(s[0]=='1' && s[n-1]=='0') { reverse(s.begin(),s.end()); for(int i=0;i<n-1;i++) { if(s[i+1]==s[i] && s[i]=='1') { cout<<"YES\n"; return; } } cout<<"NO\n"; } }
|
方法二:可以想到应该尽可能地少让1和0进行操作,应该尽量让全0串化为一个0。那么最终结果就会使一个由孤立0和1(连续或者不连续)组成的串。如果0的个数小于1则有解,否则无解。
#include <bits/stdc++.h> #define lowbit(x) x&(-x) const int MAXN=2e5+10; const int mod=998244353; using namespace std; using ll=long long; void solve(); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t=1; cin>>t; while(t--) { solve(); } } void solve() { int n; cin>>n; string s; cin>>s; int one=count(s.begin(),s.end(),'1'); int zero=0; for(int i=0;i<s.size();i++) { if(s[i]=='0' && (i==0 || s[i-1]=='1')) { zero++; } } if(zero<one) { cout<<"YES\n"; } else { cout<<"NO\n"; } }
|
C
观察样例发现都是以\(n\)结尾的,我们以样例四进行研究。
要使得单增,并且最长,且\(a_{i}|a_{i-1}=n
(2\leq i \leq
k)\),我们进行倒推,那么第二大应该越大越好,同理推导下去。
14: 1 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0
|
可以发现推导的结果如上。可以发现:从小到大,0一直在右移。我们可以统计\(n\)的组成,并且模拟这个过程,逐个进行计算输出。不过需要注意一些情况需要特判。
如果原来的数只有一个1(二进制),那么直接输出即可。
#include <bits/stdc++.h> #define lowbit(x) x&(-x) const int MAXN=2e5+10; const int mod=998244353; using namespace std; using ll=long long; void solve(); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t=1; cin>>t; while(t--) { solve(); } } void solve() { ll n; cin>>n; vector<ll> a; int k=0; ll m=n; int cnt=0; while(n) { if(n&1) { a.push_back(k); } n>>=1; k++; } if(a.size()==1) { cout<<1<<"\n"; cout<<m<<"\n"; return; } cout<<a.size()+1<<"\n"; cnt=a.size()-1; for(int i=0;i<a.size();i++) { ll ans=0; for(int j=0;j<a.size();j++) { if(j!=cnt) { ans+=(1ll<<a[j]); } } cout<<ans<<" "; cnt--; } cout<<m<<"\n"; }
|
另外一种写法:
可以发现我们可以使用位运算进行操作,只需要获取是哪个位置的1,并且进行异或运算即可。
#include <bits/stdc++.h> #define lowbit(x) x&(-x) const int MAXN=2e5+10; const int mod=998244353; using namespace std; using ll=long long; void solve(); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t=1; cin>>t; while(t--) { solve(); } } void solve() { ll n; cin>>n; int one=__builtin_popcountll(n); if(one==1) { cout<<1<<"\n"<<n<<"\n"; return; } cout<<one+1<<"\n"; for(int i=63;i>=0;i--) { if((n>>i) & 1) { cout<<(n^(1ll<<i))<<" "; } } cout<<n<<"\n"; }
|