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;
}
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;
}
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);
}
}
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;
}
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;
}
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;
}


浙公网安备 33010602011771号