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 - 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
", 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
", 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
");
    printf("%d
", 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, &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;
}
原文地址:https://www.cnblogs.com/cocottt/p/6764999.html