牛客周赛 Round 108题解
ICPC World Finals
思路:直接根据题意去判断即可
#include<bits/stdc++.h>
using namespace std;
int a,b,c,d;
signed main()
{cin>>a>>b>>c>>d; int flag=0;if(b<60||c<60||d<60)flag=1;if(a<425&&flag==1){cout<<"YES\n";}elsecout<<"NO\n";
}
小苯的数字排序
思路:用两个vector去收集奇数和偶数,然后排序,然后将偶数先输出,奇数后输出即可解决这个问题
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n;
int a[200005];
void solve()
{vector<int> ji;vector<int> ou;cin>>n;for(int i=1;i<=n;i++){cin>>a[i];if(a[i]%2==1)ji.push_back(a[i]);elseou.push_back(a[i]);}sort(ou.begin(),ou.end());sort(ji.begin(),ji.end());for(int i:ou){cout<<i<<" ";}for(int i:ji){cout<<i<<" ";}cout<<"\n";
}
signed main()
{cin>>t;while(t--){solve();}return 0;
}
小苯的数字合并
思路:我们仔细想一下会发现答案的结果只与数组的元素个数有关,与值无关,我们在之上去写会发现,其实就是2的n-1次方,直接写个快速幂取模即可得到最后的答案
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n;
int a[200005];
int mod=998244353;
int fast(int a,int b)
{int base=1;while(b){if(b%2==1)base=base*a%mod;b/=2;a=a*a%mod;}return base;
}
void solve()
{cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}cout<<fast(2,n-1)<<"\n";return ;
}
signed main()
{cin>>t;while(t--){solve();}return 0;
}
小苯的子序列权值
思路:因为是按位与,所以只有所有数都是奇数的时候,最终的权值才是奇数,否则就是偶数,因此我们可以用数学的方法来解决,每个数都有两种可能,因此我们所有的选择的可能数是2^n-1
假设我们奇数的个数是x,那么选中的只有奇数的可能情况有2^x-1,用这两个数相减就是最终答案了
#include<bits/stdc++.h>
using namespace std;
#define int long longint t;
int n;
int a[200005];
int mod=998244353;
int fast(int a,int b)
{int base=1;while(b){if(b%2==1){base=base*a%mod;}a=a*a%mod;b/=2;}return base;
}
void solve()
{vector<int> ji,ou;cin>>n;for(int i=1;i<=n;i++){cin>>a[i];if(a[i]%2==1)ji.push_back(a[i]);elseou.push_back(a[i]);}cout<<(fast(2,n)-fast(2,ji.size())+mod)%mod<<"\n";
}
signed main()
{cin>>t;while(t--)solve();return 0;
}
小苯的有趣数
思路:我们可以先将范围内的所有除了0以外的有趣的数存到一个num数组里面,然后用bitsit去递推状态,类似于动态规划,我们只要找到f[n][sum]的状态是否为1即可
我们的f[i][j]表示的意思是,是否能将j分成i个有趣的数,如果可以,值就是1,否则的话,前n-1个数事0,最后一个数事sum
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n;
int a[200005];
bitset<200005> f[205];
vector<int> num;
void ini()
{for(int i=1;i*i<40001;i++){string s=to_string(i*i);int sum=0;for(char c:s){sum+=c-'0';}int q=sqrt(sum);if(q*q==sum){num.push_back(i*i);}}f[0][0]=1;for(int i=0;i<100;i++){for(int x:num){f[i+1]|=f[i]<<x;}}
}
void solve()
{cin>>n;int sum=0;for(int i=1;i<=n;i++){cin>>a[i];sum+=a[i];}cout<<(f[n][sum]?n:n-1)<<"\n";
}
signed main()
{ini();cin>>t;while(t--){solve();}return 0;
}