目录
因为首部不为零,故我们从第二个字符开始遍历,如果遇到第一个不为‘0’的字符,那么从此开始的字符串就是b的最大值,然后判断a和b的大小,视情况输出即可
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define INF 0x3f3f3f3f
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define pb push_back
#define vct vector
#define checkbit __builtin_popcount
#define gcd __gcd
#define use int T;cin>>T;while(T--)
#define LEN length()
#define all(a) a.begin(),a.end()
template<class T> bool mmax(T &u, T v) { return u < v ? (u = v, 1) : 0; }
template<class T> bool mmin(T &u, T v) { return u > v ? (u = v, 1) : 0; }
#define lowbit(x) (x&(-x))
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int,int>pii;
signed main()
{IOS
use{
string a;cin>>a;
int t=-1;
for(int i=1;i<a.LEN;i++){
if(a[i]!='0'){
t=i;break;
}
}
if(t==-1||(a.substr(0,t)>=a.substr(t)&&t==(a.LEN-t))||t>(a.LEN-t))cout<<"-1"<<endl;
else
cout<<a.substr(0,t)<<" "<<a.substr(t)<<endl;
}
return 0;
}
创建一个新字符串t,是在s的基础上可以交换和删除,删除会花费1费用,最终使得?,因为s是不变的,故我们考虑s当中'0'和'1'的个数:设'0'的个数为cnt0, '1'的个数为cnt1
解释大概有些抽象,我们结合代码来看?
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define INF 0x3f3f3f3f
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define pb push_back
#define vct vector
#define checkbit __builtin_popcount
#define gcd __gcd
#define use int T;cin>>T;while(T--)
#define LEN length()
#define all(a) a.begin(),a.end()
template<class T> bool mmax(T &u, T v) { return u < v ? (u = v, 1) : 0; }
template<class T> bool mmin(T &u, T v) { return u > v ? (u = v, 1) : 0; }
#define lowbit(x) (x&(-x))
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int,int>pii;
signed main()
{IOS
use{
string a;cin>>a;
int cnt=0;
int _1=-1,_0=-1;
for(int i=0;i<a.LEN;i++){
if(a[i]=='0'){cnt++;_0=i;}
else _1=i;
}
if(cnt==(a.LEN-cnt))cout<<"0"<<endl;
else if(_1==-1||_0==-1)cout<<a.LEN<<endl;
else {
int ans=0;
if(cnt>a.LEN-cnt){
int t=a.LEN-cnt;
for(int i=0;i<a.LEN;i++){
if(a[i]=='0'&&t>0)t--;
if(t==0){
if(i+1<a.LEN&&a[i+1]!='1')
{ans=a.LEN-i-1;
break;}
}
}
}
if(cnt<a.LEN-cnt){
int t=cnt;
for(int i=0;i<a.LEN;i++){
if(a[i]=='1'&&t>0)t--;
if(t==0){
if(i+1<a.LEN&&a[i+1]!='0')
{ans=a.LEN-i-1;
break;}
}
}
}
cout<<ans<<endl;
}
}
return 0;
}
给一个空的集合multiset,1添加,2代表查询是否有multiset的子集和等于
我们从二进制的角度考虑,当添加一个时,也就是在查询w的时候x位所能做的贡献就加一,查询w的时候也将w转为二进制,我们从零开始遍历集合当中的二进制位,如果当前组成w需要该位,那么集合该位的个数就减一,如果不需要当前位,那么就将多余的位进到下一位为w使用下一位做准备,如果查询到w需要该位,但该位为零的情况输出NO.
对于第一个样例的第一次查询:
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define INF 0x3f3f3f3f
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define pb push_back
#define vct vector
#define checkbit __builtin_popcount
#define gcd __gcd
#define use int T;cin>>T;while(T--)
#define LEN length()
#define all(a) a.begin(),a.end()
template<class T> bool mmax(T &u, T v) { return u < v ? (u = v, 1) : 0; }
template<class T> bool mmin(T &u, T v) { return u > v ? (u = v, 1) : 0; }
#define lowbit(x) (x&(-x))
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int,int>pii;
signed main()
{IOS
int n;cin>>n;
vct<int>cnt(32);
while(n--){
int a,b;cin>>a>>b;
if(a==1){
cnt[b]++;
}
else {bool isok=1;
vct<int>sit(32);
vct<int>cntx(32);
cntx=cnt;
int o=0;
while(b>0){
sit[o++]=b&1;
b>>=1;
}
for(int i=0;i<32;i++){
if(sit[i]){
if(!cntx[i]){
isok=0;
break;
}
cntx[i]--;
}
if(cntx[i]){
int x=(cntx[i]/2);
cntx[i+1]+=x;
cntx[i]-=x*2;
}
}
if(isok)yes;
else no;
}
}
return 0;
}