2020 ICPC Shanghai Site

A. Wowoear

B. Mine Sweeper II

对比两个图中不同的块的个数,如果小于 M * N / 2 就直接输出A,否则输出A格子翻转之后的图

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int n, m;
char s1[N][N], s2[N][N], s3[N][N];
int solve(char sa[N][N], char sb[N][N]) 
{
    int cnt = n * m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cnt -= sa[i][j] == sb[i][j];
    return cnt;
}
int main() 
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%s", s1[i] + 1);
    for (int i = 1; i <= n; i++) scanf("%s", s2[i] + 1);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            s3[i][j] = (s1[i][j] == '.' ? 'X' : '.');
    if (solve(s1, s2) <= n * m / 2) 
    {
        for (int i = 1; i <= n; i++) puts(s1[i] + 1);
        return 0;
    }
    for (int i = 1; i <= n; i++) puts(s3[i] + 1);
    return 0;
}
View Code

C. Sum of Log

这道题可以采用数位dp的方法。
由于 i & j = 0,所以 (i + j) 一定不会进位,log2(i + j) 一定是他们的最高位1的位置。
令 dp[len][limit1][limit2][zero] 表示: 当前长度为 len,i 的高位限制,j 的高位限制,当前已枚举的值是否是0 的贡献。
枚举下一个数,dp一下即可。
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
int dp[40][2][2][2];
int l[40], r[40];
int x, y;
int dfs(int len, bool limit1, bool limit2, bool zero)
{
    if (len == -1) return 1;
    if (dp[len][limit1][limit2][zero] != -1) return dp[len][limit1][limit2][zero];
    int a = (limit1 ? l[len] : 1), b = (limit2 ? r[len] : 1);
    int ans = 0;
    for (int i = 0; i <= a; i++)
    {
        for (int j = 0; j <= b; j++)
        {
            if (i & j) continue;
            // t是之后每个方案的贡献
            int t = -1;
            if (zero && (i || j)) t = len + 1; //当前位是最高位1,log+1
            else t = 1; //当前位不是最高位1,那么只需要为最高位求方案数即可.
            ans = (ans + 1ll * dfs(len - 1, limit1 && i == a, limit2 && j == b, zero && !i && !j) * t % mod) % mod;
        }
    }
    return dp[len][limit1][limit2][zero] = ans;
}
int main()
{
    int cass;
    for (scanf("%d", &cass); cass; cass--)
    {
        memset(dp, -1, sizeof dp);
        scanf("%d%d", &x, &y);
        int len = 0;
        while (x || y)
        {
            l[len] = (x & 1), r[len] = (y & 1);
            x >>= 1, y >>= 1;
            len++;
        }
        printf("%d\n", (dfs(len - 1, 1, 1, 1) - 1 + mod) % mod);
    }
    return 0;
}
View Code

D. Walker

主要考虑两种情况:1.相遇后扭头 2.相遇后不扭头。
对于第一种情况可以用二分的方式寻找p1,p2的相遇点,对每个相遇点分别求出两个人走完自己的路程所需最小时间。
对于第二种情况就更简单了,直接相对走到头就可以了。
#include <bits/stdc++.h>
using namespace std;
inline double calc(double l, double r, double v, double p)
{
    return (min(p - l, r - p) + r - l) / v;
}
int main()
{
    int cass;
    for (cin >> cass; cass; cass--)
    {
        double n, p1, v1, p2, v2;
        cin >> n >> p1 >> v1 >> p2 >> v2;
        if (p1 > p2) swap(p1, p2), swap(v1, v2);
        double res = min(calc(0, n, v1, p1), calc(0, n, v2, p2));
        res = min(res, max((n - p1) / v1, p2 / v2));
        double l = p1, r = p2;
        for (int i = 0; i < 100; i++)
        {
            double mid = (l + r) / 2;
            double res1 = calc(0, mid, v1, p1), res2 = calc(mid, n, v2, p2);
            res = min(res, max(res1, res2));
            if (res1 > res2) r = mid;
            else l = mid;
        }
        printf("%.10f\n", res);
    }
}
View Code

E. The Journey of Geor Autumn

F. Fountains

G. Fibonacci

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll n; cin >> n;
    ll even = n % 3, odd = n / 3;
    ll ans = odd * (odd + 1) + odd * even + (odd - 1) * 3 * odd / 2;
    cout << ans;
    return 0;
}
View Code

H. Rice Arrangement

I. Sky Garden

#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    double ans = (2 * m + 2 * m * n) * n / 2;
    if (m == 1) ans = 0;
    for (int i = 1; i <= n; i++)
    {
        double len = PI * i / m;
        for (int j = i; j <= n; j++)
        {
            double now = j - i;
            for (int p = 1; p <= m - 1; p++) 
                now += min(len * p + (j - i), (double)i + j) * 2;
            now += i + j;
            if (j == i) ans += now * m;
            else ans += now * m * 2;
        }
    }
    printf("%.10f\n", ans);
    return 0;
}
View Code

J. Octasection

K. Traveling Merchant

L. Traveling in the Grid World

M. Gitignore

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map<string, ll> q, vis;
string a[1001];
int main()
{
    int cass;
    for (cin >> cass; cass; cass--)
    {
        ll m, n;
        cin >> n >> m;
        vis.clear();
        q.clear();
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1; i <= m; i++)
        {
            string x, y;
            cin >> x;
            for (int j = 0; j < x.size(); j++)
            {
                y += x[j];
                if (x[j] == '/') vis[y] = 1;
            }
        }
        ll s = 0;
        for (int i = 1; i <= n; i++)
        {
            string x;
            int flag = 0;
            for (int j = 0; j < a[i].size(); j++)
            {
                x += a[i][j];
                if (a[i][j] == '/')
                {
                    if (q[x])
                    {
                        flag = 1;
                        break;
                    }
                    if (!vis[x])
                    {
                        flag = q[x] = 1;
                        s++;
                        break;
                    }
                }
            }
            s += !flag;
        }
        cout << s << "\n";
    }
    return 0;
}
View Code
posted @ 2022-01-03 19:26  ゼロツー  阅读(184)  评论(0)    收藏  举报
Live2D Title