A - Boboniu Likes to Color Balls
判断奇偶。由题意可得,最多一个奇数。r,g,b同时减一,奇偶互换。
w加3,导致奇偶改变。而又因为加上偶数,奇偶性质不变,所以我们只需要观察原来的rgbw,和操作一次的rgbw。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int T, r, g, b, w;
int main() {
T = read();
while (T--) {
r = read(), g = read(), b = read(), w = read();
int f[4];
f[0] = r & 1; f[1] = g & 1; f[2] = b & 1; f[3] = w & 1;
int cnt = 0;
up(i, 0, 4) {
if (f[i])cnt++;
}
if (cnt == 1 || cnt == 0) { puts("Yes"); }
else {
if (r&&g&&b) {
cnt = 0;
r--, g--, b--, w += 3;
f[0] = r & 1; f[1] = g & 1; f[2] = b & 1; f[3] = w & 1;
up(i, 0, 4) {
if (f[i])cnt++;
}
if (cnt == 1 || cnt == 0) { puts("Yes"); }
else puts("No");
}
else puts("No");
}
}
return 0;
}
B - Boboniu Plays Chess
构造。因为可以在一行随意跑。所以我们优先跑到第一行。然后向左跑,再向右跑,跑到最后一行的时候,我们向上走一行,到达下一行即可。中途设置vis标记,如果被标记了,跳过。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int n, m, sx, sy;
int vis[105][150];
int main() {
n = read();
m = read();
sx = read(), sy = read();
vis[sx][sy] = 1;
cout << sx << " " << sy << endl;
vis[1][sy] = 1;
cout << 1 << " " << sy << endl;
upd(i, 1, m) {
if (i == sy)continue;
vis[1][i] = 1;
cout << 1 << " " << i << endl;
}
upd(i, 2, n) {
if (i & 1) {
upd(j, 1, m) {
if (vis[i][j])continue;
vis[i][j] = 1;
cout << i << " " << j << endl;
}
}
else {
dwd(j, m, 1) {
if (vis[i][j])continue;
vis[i][j] = 1;
cout << i << " " << j << endl;
}
}
}
return 0;
}
C - Boboniu and Bit Operations
贪心
所以预处理出来一个
n
×
m
×
k
n \times m \times k
n×m×k的矩阵。表示第i个和第j个做&运算,出来的结果的第k位,是0还是1。
又有运算 | 的性质,我们可以知道,该位置是1,当且仅当该位置至少一个1,全零的时候,才可能是0。所以紧接着我们遍历矩阵。
对于第i位来说,如果当前所有
n
×
m
n\times m
n×m中,都存在某一个对应位置,使得
g
r
p
[
i
]
[
j
]
[
k
]
=
=
0
grp[i][j][k]==0
grp[i][j][k]==0那么该位置可以取零。然后接着将这一个位置是零的数字全部提取出来,其他的扔掉,继续上述操作。
否则的话,该位置必定为1,进入下一位置,没有影响。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 2e2 + 10;
int n, m;
int a[N], b[N];
int vis[N][N][11];
int bits[N][N][11];
int main() {
n = read(), m = read();
upd(i, 1, n)a[i] = read();
upd(i, 1, m)b[i] = read();
upd(i, 1, n) {
upd(j, 1, m) {
int temp = a[i] & b[j];
dwd(k, 9, 0) {
if (temp >> k & 1)bits[i][j][k] = 1;
vis[i][j][k] = 1;
}
}
}
int ans = 0;
dwd(k, 9, 0) {
bool flag = 0;
upd(i, 1, n) {
int cnt = 0;
upd(j, 1, m) {
if (bits[i][j][k] == 0 && vis[i][j][k])cnt++;
}
if (cnt == 0) { ans |= (1 << k); flag = 1; break; }
}
if (!flag) {
upd(i, 1, n) {
int cnt = 0;
upd(j, 1, m) {
if (bits[i][j][k] == 0 && vis[i][j][k])vis[i][j][k] = 1;
else {
upd(k, 0, 9)vis[i][j][k] = 0;
}
}
}
}
}
cout << ans << endl;
return 0;
}
D - Boboniu Chats with Du
贪心即可。
枚举我们选中了多少个会被封禁的日子,然后对于剩下的日子,我们只需要摆放还剩下的免费的发言日子即可。
同时注意到,如果我们永远将最大的val放到最后面,那么被封禁的日子是x次,但我们得到了x+1个val,这样肯定是最优的。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
ll a[N];
ll n, d, m;
int s1[N], s2[N];
ll pre[N];
int main() {
n = read(), d = read(), m = read();
int cnt1 = 0, cnt2 = 0;
upd(i, 1, n) {
a[i] = read();
if (a[i] <= m)s1[++cnt1]=a[i];
else s2[++cnt2]=a[i];
}
sort(s1 + 1, s1 + cnt1 + 1, [&](int a, int b) {return a > b; });
sort(s2 + 1, s2 + cnt2 + 1, [&](int a, int b) {return a > b; });
upd(i, 1, cnt1)pre[i] = pre[i - 1] + s1[i];
ll ans = pre[cnt1];
ll sum = 0;
upd(i, 1, cnt2) {
ll day = i;
sum += s2[i];
day = (day - 1)*(d + 1) + 1;
day = n - day;
if (day < 0)break;
ll temp = min((ll)cnt1, day);
ans = max(ans, pre[max(temp, 0ll)] + sum);
}
cout << ans << endl;
return 0;
}
E - Boboniu Walks on Graph
题意就是我们需要若干个环,组成原图。
可以知道,如果把有向图的达到的点,全部放在一个集合中,那么该集合一定是
[
1
,
n
]
[1,n]
[1,n]的一个排列。
所以我们进行hash集合。判断最后是否能凑出
[
1
,
n
]
[1,n]
[1,n]的hash值即可。(利用
H
x
H^x
Hx进行hash,就能使用结合律)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 2e5 + 10;
const int H = 2333333;
int n, m, k;
vector<pir>vec[N];
vector<int>id[N];
ull Hash[N];
ull sumH[10][10];
ull tot = 0;
int ans = 0;
void dfs(int pos,ull tempsum) {
if (pos == k + 1) {
if (tempsum == tot) {
ans++;
}
return;
}
else {
upd(i, 1, pos) {
dfs(pos + 1, tempsum + sumH[pos][i]);
}
}
}
int main() {
n = read(), m = read(), k = read();
int u, v, w;
upd(i, 1, m) {
u = read(), v = read(), w = read();
vec[u].push_back(make_pair(w, v));
}
Hash[0] = 1;
upd(i, 1, n) {
Hash[i] = Hash[i - 1] * H;
tot += Hash[i];
sort(vec[i].begin(), vec[i].end());
id[vec[i].size()].push_back(i);
}
upd(i, 1, k) {
upd(j, 1, i) {
ull sum = 0;
for (auto k : id[i]) {
sum += Hash[vec[k][j - 1].second];
}
sumH[i][j] = sum;
}
}
dfs(1, 0);
cout << ans << endl;
return 0;
}
F. Boboniu and String
我们将
N
N
N的个数当作y轴,
B
B
B的个数当作x轴。题意的操作就是将点移动到
(
x
+
1
,
y
)
,
(
x
−
1
,
y
)
,
(
x
,
y
−
1
)
,
(
x
,
y
+
1
)
,
(
x
−
1
,
y
−
1
)
,
(
x
+
1
,
y
+
1
)
)
(x+1,y),(x-1,y),(x,y-1),(x,y+1),(x-1,y-1),(x+1,y+1))
(x+1,y),(x−1,y),(x,y−1),(x,y+1),(x−1,y−1),(x+1,y+1))我们便可以进行线性规划,得出x取值,y取值,最后尽可能去右上角即可(因为本质上是一个矩形,被两个斜线切开)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 5e5 + 10;
char s[N];
int x[N], y[N];
int n;
int ansb, ansn;
bool check(int l, int getans) {
int xmin = -1e9, xmax = 1e9, ymin = -1e9, ymax = +1e9, pmin = -1e9, pmax = +1e9;
upd(i, 1, n) {
xmin = max(xmin, x[i] - l);
xmax = min(xmax, x[i] + l);
ymin = max(ymin, y[i] - l);
ymax = min(ymax, y[i] + l);
pmin = max(pmin, y[i] - x[i] - l);
pmax = min(pmax, y[i] - x[i] + l);
}
if (xmin < 0)xmin = 0; if (ymin < 0)ymin = 0;
if (xmin > xmax || ymin > ymax || pmin > pmax)return 0;
int ppmin = ymin - xmax;
int ppmax = ymax - xmin;
if (ppmin > pmax || ppmax < pmin)return 0;
if (getans) {
ansn = min(ymax, pmax + xmax);
ansb = min(xmax, ansn - pmin);
}
return 1;
}
int main() {
n = read();
upd(i, 1, n) {
scanf("%s", s + 1);
int sz = strlen(s + 1);
upd(j, 1, sz) {
if (s[j] == 'B')x[i]++;
else y[i]++;
}
}
int lf = -1;
int rt = 1e9;
while (rt > lf + 1) {
int mid = (rt + lf) >> 1;
if (check(mid, 0))rt = mid;
else lf = mid;
}
check(rt, 1);
cout << rt << endl;
upd(i, 1, ansb)putchar('B');
upd(i, 1, ansn)putchar('N');
return 0;
}