A、Boboniu Likes to Color Balls
水题,但是写起来挺麻烦的……
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=500;
ll a[N];
int main()
{
int t,n;
int r,g,b,w;
cin >> t;
while(t--)
{
int js=0,os=0,a0=0;
for(int i=0;i<4;i++){
cin >> a[i];
if(i!=3){
if(a[i]%2==0)
os++;
else js++;
}
if(i!=3&&a[i]==0)
a0++;
}
if(a0==3||(a0==2&&a[3]%2==0))
cout << "Yes" <<endl;
else if(a0!=0){
if(js>1||(js==1&&a[3]%2==1))
cout << "No" <<endl;
else
cout << "Yes" <<endl;
}
else{
if(os==3||js==3)
cout << "Yes" <<endl;
else if((os==2&&a[3]%2==0)||(js==2&&a[3]%2==1))
cout << "Yes" <<endl;
else
cout << "No" <<endl;
}
}
return 0;
}
Boboniu Plays Chess
水题,遍历每一行即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=500;
int n,m;int x0,y0;
int a[N][N];
void work(int l,int pd){//1是逆序,0是正序
if(l==n+1)
return;
if(l==x0)
work(l+1,pd);
else{
if(pd == 1){
for(int i=m;i>0;i--)
cout << l << " " << i <<endl;
work(l+1,0);
}else{
for(int i=1;i<=m;i++)
cout << l << " " << i <<endl;
work(l+1,1);
}
}
}
int main()
{
//int t,n;
cin >> n >> m >> x0 >> y0;
a[x0][y0] = 1;
cout << x0 << " " << y0 <<endl;;
for(int i=1;i<=m;i++){
if(a[x0][i]==0)
cout << x0 << " " << i <<endl;
}
if(x0!=1)
work(1,1);
else
work(2,1);
return 0;
}
C、Boboniu and Bit Operations
题意:数组a和b,问1<=a<=n,1<=j<=m,将所有的c[i]=a[i]&b[j]取或的最小值为多少,i每个只取一次,j每个可以取任意次。
思路:当时没想出来怎么做,后来找了题解。
从小到大枚举这个最小值,因为它数据最大为
2
9
2^9
29=512,直接枚举即可。
然后进行判断的时候只需要判断在每个a[i]是否有一个b[j]有存在 a[i]&b[j] = s(s为枚举的这个最小值)即可,如果都有一个 a[i]&b[j] = s,那么n个数的或就是这个s,得出答案。
参考博客
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=500;
int n,m,a[209],b[209];
bool work(int s)
{
for(int i=1; i<=n; i++)
{
int flag=0;
for(int j=1; j<=m; j++)
{
int temp = (a[i]&b[j]);
if((temp|s)==s)
flag=1;
if(flag) break;
}
if(flag==0)
return false;
}
return true;
}
int main()
{
cin >> n >> m;
for(int i=1; i<=n; i++)
cin >> a[i];
for(int i=1; i<=m; i++)
cin >> b[i];
for(int i=0; i<(1<<9); i++)
if(work(i))
{
cout << i <<endl;
return 0;
}
}
D、Boboniu Chats with Du
题意:给 n 个发言后可以得到的快乐值,你可以按任何顺序在群里发言,如果当天发言得到的快乐值为
k
i
k_i
ki的话,当
k
i
k_i
ki > m 时,你会被禁 d 天的禁言(禁言从第二天开始),n 天后你的快乐值的和最大是多少。
思路:贪心。本质就是在算用了多少个大于m的数,枚举用了多少个大于m的数即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+10;
int a[N];
ll h[N],s[N],cnt1,cnt2;
bool cmp(int x,int y){
return x > y;
}
int main()
{
int n,d,m,t;
cin>>n>>d>>m;
for(int i=1;i<=n;i++) {
cin>>t;
if(t>m) h[++cnt1] = t;
else s[++cnt2] = t;
}
sort(h+1,h+1+cnt1,cmp);
sort(s+1,s+1+cnt2,cmp);
for(int i=1;i<=cnt1;i++)
h[i] += h[i-1];
for(int i=1;i<=n;i++)
s[i] += s[i-1];
ll ans = s[cnt2];
for(int num=1;num<=cnt1;num++){//枚举禁言次数
ll k = (ll)(num-1)*(d+1)+1;//禁言num次时用多少天
if(k <= n)
ans = max(ans,h[num]+s[n-k]);//禁言当天的快乐值+剩余天数中不被禁言的快乐值
}
cout<<ans<<endl;
return 0;
}