2022河南萌新联赛第(七)场:南阳理工学院ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛牛客竞赛OJ (nowcoder.com)
2022河南萌新联赛第(七)场:南阳理工学院ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛牛客竞赛OJ (nowcoder.com)
1.B-龍_2022河南萌新联赛第(七)场:南阳理工学院 (nowcoder.com)
每次操作1刚好可以消除一次操作2,考虑n个团块,最后总共只需要n次操作。那就看a,b中谁更小我就操作谁更多次。
#include<bits/stdc++.h>
using namespace std;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define feh(i,x,y) for(int i=x;i>=y;i--)
#define int long long
#define pb push_back
#define IOS cin.tie(0)->sync_with_stdio(false);
#define inf 0x7fffffff
#define endl "\n"
string s;
int n,a,b,x,cnt;
void slove(){
cnt=0;
cin>>n>>a>>b>>x;
cin>>s;
int la='1';
for(int i=0;i<n;i++){
if(la!=s[i]&&s[i]=='0') cnt++;
la=s[i];
}
if(cnt==0){
cout<<"Yes"<<endl;
cout<<x<<endl;
return;
}
int ans=(cnt-1)*min(a,b)+b;
if(ans<=x){
cout<<"Yes"<<endl;
cout<<x-ans<<endl;
}
else{
cout<<"No"<<endl;
}
}
signed main(){
int t;
cin>>t;
while(t--){
slove();
}
return 0;
}
2.C-机智的我_2022河南萌新联赛第(七)场:南阳理工学院 (nowcoder.com)
感觉是个玄学题。
#include<bits/stdc++.h>
using namespace std;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define feh(i,x,y) for(int i=x;i>=y;i--)
#define int long long
#define pb push_back
#define IOS cin.tie(0)->sync_with_stdio(false);
#define inf 0x7fffffff
#define endl "\n"
int n,k;
signed main(){
cin>>n>>k;
if(k) cout<<"Why not";
else cout<<"Whatever";
return 0;
}
3.D-疯狂星期八_2022河南萌新联赛第(七)场:南阳理工学院 (nowcoder.com)
很明显倒着取是更优的。我们考虑倒着取最多之只能取100个。所以我们直接考虑开一个100体积的01背包,只要花费小于m就代表取当前这么多物品时有可能的。
#include<bits/stdc++.h>
using namespace std;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define feh(i,x,y) for(int i=x;i>=y;i--)
#define int long long
#define pb push_back
#define IOS cin.tie(0)->sync_with_stdio(false);
#define inf 0x7fffffff
#define endl "\n"
const int N=1e5+100;
int n,m;
int f[110];//背包体积只有100//只要此时的花费是小于m的即可
int w[N];
signed main(){
cin>>n>>m;
for(int i=1;i<=105;i++) f[i]=m+1;
for(int i=1;i<=n;i++) cin>>w[i];
f[0]=0;
for(int i=n;i>=1;i--){
for(int j=100;j>=1;j--){
f[j]=min(f[j],f[j-1]+w[i]+(j-1)*i);
}
}
for(int i=100;i>=0;i--){
if(f[i]<=m){
cout<<i<<endl;
return 0;
}
}
return 0;
}
4.F-数对_2022河南萌新联赛第(七)场:南阳理工学院 (nowcoder.com)
思考一下&值什么时候大于^值,只要两个数最高位1时相同位置即可。所以问题就转化成立区间内有多少对最高位1位置相同。由于时相等,所以两数都是0也可以。将数组转化成存最高位1出现的位置,2^0存1,最后只需要统计区间内相同数的对数即可。
#include<bits/stdc++.h>
using namespace std;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define feh(i,x,y) for(int i=x;i>=y;i--)
#define int long long
#define pb push_back
#define IOS cin.tie(0)->sync_with_stdio(false);
#define inf 0x7fffffff
#define endl "\n"
/*
&值大与^则需要考虑两个数最高位1时相同位置即可
都是0也可以
然后只要找区间内出现相同值的对数即可
只有0-31这几个数
*/
const int N=1e5+100;
int n,m;
int a[N];
int sum[N][40];
void change(int &x){
int tot=0;
int ans=0;
while(tot<31){
if(x&1) ans=tot+1;
tot++;
x>>=1;
}
x=ans;
}
signed main(){
cin>>n>>m;
fel(i,1,n){
cin>>a[i];
change(a[i]);
// cout<<a[i]<<" ";
}
//cout<<endl;
for(int i=1;i<=n;i++) sum[i][a[i]]=1;
for(int i=0;i<=31;i++){
for(int j=1;j<=n;j++){
sum[j][i]+=sum[j-1][i];
}
}
while(m--){
int x,y;
int ans=0;
cin>>x>>y;
for(int i=0;i<=31;i++){
ans+=(sum[