2021牛客暑期多校訓練營8
A. Ares, Toilet Ares
- 題意
廁所戰神,去廁所一次就有\(\frac{z_i - y_i}{z_i}\)的可能拿到一段長度為\(x_i\)的代碼,只有代碼長度累計到l時,即可通過題目\(K\),並且可以通過自己的智商解決a道簡單題,求能完成題目的數量
- 思路
求\(a+\prod_{i=1}^n(z - y) / z\)即可,注意逆元和分開求即可。
code :
void solve(){
int n,m,k,a,l;
cin >> n >> m >> k >> a >> l;
ll d = a;
ll up = 1, down = 1;;
for(int i = 1;i <= k;i ++) {
ll x,y,z;
cin >> x >> y >> z;
if(x == 0) continue;
d = (d * z) % mod;
up = up * (z - y) % mod;
down = down * (pow_mod(z, mod - 2)) % mod;
}
ll ans = ((d + up) % mod + mod) * down % mod;
cout << ans << endl;
}
D. OR
- 題意
給出兩個長度為\(n - 1\)的序列\(b\)和\(c\),需要構造一個長度為n的序列a,要求\(b_i = a_{i-1}\ or\ a_i, c_i = a_{i-1} + a_i\), 問最多能構造出幾個序列\(a\).
- 思路
首先要知道定理: \(a + b = a\ or\ b + a\ and\ b\), 然后枚舉\(a_1\)即可,判斷是否可行即可。
思考一下,什么情況\(a_{i-1}\)可以取一種或者兩種,那么當
- \((a_i\ or \ a_{i-1} = 1) \&\& (a_i\ and\ a_{i-1} = 1)\),這樣當前位\(a_i\)和\(a_{i-1}\)都是1
- 同時為0的情況也一樣,只能為0
- \((a_i\ or \ a_{i-1} = 1) \&\& (a_i\ and\ a_{i-1} = 0)\),那么\(a_i\)和\(a_{i-1}\)就有兩種選法(1,0)和(0,1).
code :
int b[N], c[N];
int a[N];
void solve(){
int n;
cin >> n;
fep(i,2,n) cin >> b[i];
fep(i,2,n) {
cin >> c[i];
c[i] -= b[i];
}
int ans = 1;
fep(k,0,30) {
int fa = 1,fb = 1;
fep(i,2,n) {
int tb = b[i] >> k & 1;
int tc = c[i] >> k & 1;
int na = 0, nb = 0;
if(tb && tc) {
nb = fb;
}else if(tb && !tc) { // 順序變了
na = fb,nb = fa;
}else if(!tb && !tc) {
na = fa;
}
fa = na, fb = nb;
}
ans *= fa + fb;
}
cout << ans << endl;
}
E. Rise of Shadows
- 題意
問你這一年可以是閏年且是素數嘛?
- 思路
nonononono
code :
cout << "no" << endl;
F. Robots
- 題意
給一張地圖,問類型為\(i\)的機器人是否能從\(st \to ed\)。
- 只能向下走\((x,y) \to (x + 1,y)\)
- 只能想右走\((x,y) \to (x,y + 1)\)
- 都能走
- 思路
暴力加bitset記憶化
從后往前掃,用列記錄后面所有圖的可達與否即可。
code:
bitset<N * N * 2> f[N];
int a[N][N];
char str[N];
struct Query{
int x,y;
int op,id;
};
vector<Query> v[N][N];
int ans[M];
void solve(){
int n,m;
cin >> n >> m;
for(int i = 1;i <= n;i ++) {
cin >> (str + 1);
for(int j = 1;j <= m;j ++) {
a[i][j] = (str[j] - '0');
}
}
int q;
cin >> q;
for(int i = 1;i <= q;i ++) {
int op,x1,y1,x2,y2;
cin >> op >> x1 >> y1 >> x2 >> y2;
v[x1][y1].push_back({x2,y2,op,i});
}
fpp(i,n,1) {
fpp(j,m,1) {
if(!a[i][j]) {
if(!a[i][j + 1])
f[j] |= f[j + 1];
f[j][i * m + j] = 1;
}else {
f[j].reset();
}
for(auto it : v[i][j]) {
if(it.op == 2) ans[it.id] = (it.x == i);
else if(it.op == 1) ans[it.id] = (it.y == j);
else ans[it.id] = 1;
ans[it.id] &= f[j][it.x * m + it.y];
}
}
}
fep(i,1,q) {
if(ans[i]) cout << "yes" << endl;
else cout << "no" << endl;
}
}
K. Yet Another Problem About Pi
- 題意
你有一條長為\(\pi\)的線,你可以隨意構造它的形狀,變成圓都可以,然后給你一個\(w\)和\(d\), 在二維平面內,每隔\(w\)有一條豎線,每隔\(d\)有一條橫線,問你通過畫線,最多可以和多少條線段相交(豎線和橫線分開的)
- 思路
枚舉斜邊的情況和直邊的情況即可,直邊的貢獻是2,斜邊的貢獻是3,在圖上畫即可。
code :
void solve(){
double w,d;
cin >> w >> d;
double hd = min(w,d);
double hy = sqrt(w * w + d * d);
int k = floor(pi / w);
int ans = 0;
for(int i = 0;i <= min(k,10);i ++) {
if(pi - i * hd > 0) ans = max(ans, (int)(2 * i + (int)((pi - i * hd) / hy) * 3));
if(pi - i * hy > 0) ans = max(ans, (int)(3 * i + (int)((pi - i * hy) / hd) * 2));
}
cout << ans + 4 << endl;
}