Codeforces Round #354 (Div 2)
A题:
*题目描述:
给你一个1~n的排列,问只交换一次后,1和n距离的最大值。
*题解:
贪心。把1或n交换到最旁边肯定是最优的。
*代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif
#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
int main()
{
// setfile();
R int n = FastIn(), pos = n;
for (R int i = 1; i <= n; ++i)
{
R int a = FastIn();
if (a == 1 || a == n) cmin(pos, i), cmin(pos, n - i + 1);
}
printf("%d\n", n - pos);
return 0;
}
B题:
*题目描述:
有一个成三角形的酒杯台,每个杯子的容量为1,问从1号酒杯倒下t的酒,有多少个酒杯是满的。
*题解:
直接模拟。
*代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif
#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
double a[20][20];
int main()
{
// setfile();
R int n = FastIn(), t = FastIn(), ans = 0;
a[1][1] = t;
for (R int i = 1; i <= n; ++i)
for (R int j = 1; j <= i; ++j)
if (a[i][j] >= 1)
{
++ans;
R double tmp = (a[i][j] - 1) / 2.0;
a[i + 1][j] += tmp; a[i + 1][j + 1] += tmp;
}
printf("%d\n", ans );
return 0;
}
C题:
*题目描述:
给你一个长度为n,字符集为’a’和’b’的字符串。你有最多k次机会能把’a’变成’b’,’b’变成’a’。求这样操作后连续都为’a’或’b’的最长子串长度。
*题解:
二分答案。每次二分一下答案,然后枚举每个这个长度的区间,然后统计一下把这个区间都变成一种字符的代价。然后就在O(nlog2n)的时间内解决了。
*代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif
#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
#define maxn 100010
char str[maxn];
int n, k;
inline bool check(R int x)
{
R int w = 0, b = 0;
for (R int i = 1; i <= x; ++i) w += str[i] == 'a', b += str[i] == 'b';
for (R int l = 1, r = x; r <= n; ++l, ++r)
{
if (dmin(w, b) <= k) return 1;
w -= str[l] == 'a'; b -= str[l] == 'b';
w += str[r + 1] == 'a'; b += str[r + 1] == 'b';
}
return 0;
}
int main()
{
// setfile();
n = FastIn(), k = FastIn();
for (R int i = 1; i <= n; ++i) str[i] = getc();
R int left = 1, right = n + 1;
while (left < right)
{
R int mid = left + right >> 1;
if (check(mid)) left = mid + 1;
else right = mid;
}
printf("%d\n", left - 1 );
return 0;
}
D题:
*题目描述:
给你一定迷宫(详见原题的给出方式),每次你可以将所有的方格顺时针旋转90°,或者沿着方格的某个方向移动一格,问你从起点到终点的最短路。
*题解:
大爆搜题。模拟赛上没看清题目,看成只能旋转一格,于是乎10分钟构图+SPFA,然后过掉样例后就光荣Wrong Answer!早知如此就老老实实写bfs。
*代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif
#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
#define maxn 1010
char mp[maxn][maxn];
struct Queue
{
int x, y, s;
};
bool vis[maxn][maxn][4];
std::queue<Queue> q;
inline int num(R char x)
{
if (x == '+') return 15;
if (x == '-') return 10;
if (x == '|') return 5;
if (x == '^') return 1;
if (x == '>') return 2;
if (x == 'v') return 4;
if (x == '<') return 8;
if (x == 'L') return 7;
if (x == 'R') return 13;
if (x == 'U') return 14;
if (x == 'D') return 11;
if (x == '*') return 0;
}
inline bool con(R int s, R int x, R int y, R int xx, R int yy)
{
R int a = num(mp[x][y]), b = num(mp[xx][yy]);
while (s--)
{
a = (a << 1) | (a >> 3 & 1); a &= 15;
b = (b << 1) | (b >> 3 & 1); b &= 15;
}
if (yy == y - 1) return (a & 8) && (b & 2);
else if (yy == y + 1) return (a & 2) && (b & 8);
else if (xx == x - 1) return (a & 1) && (b & 4);
else if (xx == x + 1) return (a & 4) && (b & 1);
return 1;
}
int sx, sy, tx, ty, dis[maxn][maxn][4], n, m;
const int dx[5] = {0, 0, 1, -1, 0}, dy[5] = {1, -1, 0, 0, 0}, ds[5] = {0, 0, 0, 0, 1};
inline int bfs()
{
q.push((Queue){sx, sy, 0});
vis[sx][sy][0] = 1;
memset(dis, 63, sizeof(dis));
dis[sx][sy][0] = 0;
while (!q.empty())
{
R Queue now = q.front(); q.pop();
for (R int i = 0; i < 5; ++i)
{
R int nx = now.x + dx[i], ny = now.y + dy[i], ns = (now.s + ds[i]) % 4;
if (!nx || nx > n || !ny || ny > m) continue;
if (vis[nx][ny][ns] || dis[now.x][now.y][now.s] + 1 > dis[nx][ny][ns]) continue;
if (!con(ns, now.x, now.y, nx, ny)) continue;
dis[nx][ny][ns] = dis[now.x][now.y][now.s] + 1;
if (nx == tx && ny == ty) return dis[tx][ty][ns];
vis[nx][ny][ns] = 1;
q.push((Queue) {nx, ny, ns});
}
}
return -1;
}
int main()
{
// setfile();
n = FastIn(), m = FastIn();
for (R int i = 1; i <= n; ++i)
{
for (R int j = 1; j <= m; ++j)
mp[i][j] = getc();
getc();
}
sx = FastIn(), sy = FastIn(), tx = FastIn(), ty = FastIn();
if (sx == tx && sy == ty) return !printf("0\n");
printf("%d\n", bfs() );
return 0;
}
E题:
*题目描述:
给你一个多项式和多项式的一个根,有些多项式系数是未知的。求这样的多项式是否存在(合法)。
*题解:
一个奇怪的结论。分类讨论一下,有未知系数的话好像是O(1),然后讨论完剩下一个系数都是已知的多项式,用几个大质数模一下就好了。
*代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif
#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
#define maxn 100010
int a[maxn]; bool known[maxn];
const int p[5] = {1000000007, 998244353, 333333331, 23333333};
int main()
{
// setfile();
R int n, k, cnt = 0, tmp = 0; scanf("%d%d\n", &n, &k);
for (R int i = 0; i <= n; ++i)
{
R int x;
if (scanf("%d", &x) > 0) a[i] = x, known[i] = 1, tmp ^= 1;
else
{
scanf("?"); ++cnt;
}
}
if (!k)
{
if (known[0]) puts(a[0] == 0 ? "Yes" : "No");
else puts(tmp ? "Yes" : "No");
}
else if (cnt)
{
puts((cnt & 1) == (n + 1 - cnt & 1) ? "Yes" : "No");
}
else
{
R bool flag = 1;
for (R int i = 0; i < 4 && flag; ++i)
{
R long long ret = 0;
for (R int j = n; ~j; --j)
ret = (ret * k % p[i] + a[j]) % p[i];
if (ret) flag = 0;
}
puts(flag ? "Yes" : "No");
}
return 0;
}