Once, after a stressful day, Chef decided to relax and visit a casino near his house to gamble. He feels lucky and he's going to bet almost all of his money.
The game Chef is going to play in the casino consists of tossing a die with NN faces twice. There is a number written on each face of the die (these numbers are not necessarily distinct). In order to win, Chef must get the number AA on the first toss and the number BB on the second toss of the die.
The excited viewers want to know the probability that Chef will win the game. Can you help them find that number? Assume that Chef gets each face of the die with the same probability on each toss and that tosses are mutually independent.
For each test case, print a single line containing one real number — the probability that Chef will win. Your answer will be considered correct if its absolute error does not exceed 10−610−6.
Subtask #1 (20 points):
Subtask #2 (80 points): original constraints
2
5 1 1
1 1 1 1 1
2 1 1
1 2
1.0000000000
0.2500000000
【分析】统计A和B出现的频率,相乘即可。
【代码】
#include
#include
using namespace std;
int cnt[11000];
int main()
{
int T, n, a, b, i, x;
double ans;
scanf("%d", &T);
while (T--)
{
memset(cnt, 0, sizeof(cnt));
scanf("%d%d%d", &n, &a, &b);
for (i = 1; i <= n; ++i)
{
scanf("%d", &x);
cnt[x]++;
}
printf("%lf\n", (double)cnt[a] / n * cnt[b] / n);
}
return 0;
}
Chef has two integers AA and BB. He can perform the following operation on AA an arbitrary number of times (including zero):
Chef is wondering about the minimum number of operations he has to perform on AA in order to obtain BB. Compute this number or determine that it is impossible.
For each test case, print a single line containing one integer — the minimum number of operations or −1−1 if it is impossible to obtain BB from AA.
Subtask #1 (20 points): A,B≤27A,B≤27
Subtask #2 (80 points): original constraints
2
2 4
1 5
2
1
Example case 1: One optimal solution is to not shuffle anything, so Chef just adds 11twice.
Example case 2: We can obtain 55 from 11 in one operation.
【分析】根据b的奇偶性以及a和b转为二进制谁含有的1多分开讨论,需要注意,当b为偶数时,需额外考虑二进制b后缀含有几个
连续的0,然后b为1和0需要特判。
【代码】
#include
using namespace std;
long long a, b;
int cnt(long long x)
{
int c = 0;
while (x)
{
if (x % 2 == 1) ++c;
x /= 2;
}
return c;
}
int prez(long long x)
{
int c = 0;
while (x)
{
if (x % 2 == 0) ++c;
else break;
x /= 2;
}
return c;
}
int main()
{
int T, ca, cb, ans, pr;
scanf("%d", &T);
while (T--)
{
ans = 0;
scanf("%lld%lld", &a, &b);
ca = cnt(a);
cb = cnt(b);
pr = prez(b);
if (a == b) printf("0\n");
else if (b == 0)
{
printf("-1\n");
}
else if (b == 1)
{
if (a == 0) printf("1\n");
else printf("-1\n");
} else
if (b % 2 == 1)
{
if (ca == cb) printf("2\n");
else if (cb > ca) printf("%d\n", cb - ca);
else printf("2\n");
}
else
{
if (cb > ca) printf("%d\n", cb - ca + pr);
else if (ca == cb) printf("%d\n", pr);
else if (ca == pr + cb - 1) printf("1\n");
else if (ca > pr + cb - 1) printf("2\n");
else if (ca < pr + cb - 1) printf("%d\n", pr - ca + cb);
}
}
return 0;
}
Sheokand loves strings. Chef has NN strings S1,S2,…,SNS1,S2,…,SN which he wants to give to Sheokand; however, he doesn't want to give them away for free, so Sheokand must first correctly answer QQ queries Chef asks him.
In each query, Chef tells Sheokand an integer RR and a string PP. Consider Chef's strings S1S1 through SRSR. Out of these strings, consider all strings such that their longest common prefix with PP is maximum possible. Sheokand should find the lexicographically smallest of these strings.
Sheokand is busy with his exams. Can you solve the queries for him?
For each query, print a single line containing the string that satisfies the required conditions — the answer to that query.
Subtask #1 (30 points): 1≤N,R≤1,0001≤N,R≤1,000
Subtask #2 (70 points): original constraints
4
abcd
abce
abcdex
abcde
3
3 abcy
3 abcde
4 abcde
abcd
abcdex
abcde
Query 1: For strings S1S1 through S3S3, the longest common prefix is always "abc", but "abcd" is the lexicographically smallest of these three strings.
Query 2: For strings S1S1 through S3S3, the longest common prefix with maximum length is "abcde" and the only string for which it is the LCP is "abcdex", so this is the answer.
Query 3: For strings S1S1 through S4S4, the longest common prefix with maximum length is "abcde"; it is the LCP for strings "abcdex" and "abcde", but "abcde" is the lexicographically smaller string, so it is the answer.
【分析】
设: s1 为 小于目标串最大的字符串
s2为 大于等于目标串最小的字符串
对于一个字符串集合,与目标串最长公共前缀达到最长的字符串,一定是s1或s2。考虑到要输出的是字典序最小的字符串,如果是s2,直接输出即可,如果是s1, 那么s1前面可能有最长公共前缀同样长,但是字典序更小的串,但是至多不会超过25个,枚举一下即可。根据题意,不难想到针对queries中的r排序一下,按顺序逐渐将字符串插入到set中,对于每次询问,用lower_bound可以在logn时间内完成查找,再用至多25次枚举找到答案串。
【代码】
#include
#include
#include
#include
#include
#include
using namespace std;
set s;
string ss[110000];
struct jh
{
int r, id;
string ans, bj;
}qs[110000];
bool cmp1(jh x, jh y)
{
return x.r < y.r;
}
bool cmp2(jh x, jh y)
{
return x.id < y.id;
}
int min(int x, int y)
{
if (x > y) return y;
return x;
}
int getcnt(string s, string a)
{
int i, len = min(s.length(), a.length()), cnt = 0;
for (i = 0; i < len; ++i)
if (s[i] == a[i]) ++cnt;
else break;
return cnt;
}
int main()
{
int n, q, i, j, cnt1, cnt2;
set::iterator si;
scanf("%d", &n);
for (i = 1; i <= n; ++i) cin>>ss[i];
scanf("%d", &q);
for (i = 1; i <= q; ++i)
{
qs[i].id = i;
cin>>qs[i].r>>qs[i].bj;
}
sort(qs + 1, qs + 1 + q, cmp1);
for (i = 1; i <= q; ++i)
{
for (j = qs[i - 1].r + 1; j <= qs[i].r; ++j) s.insert(ss[j]);
si = s.lower_bound(qs[i].bj);
if (si == s.begin())
qs[i].ans = *si;
else if (si == s.end())
{
--si;
cnt2 = getcnt(*si, qs[i].bj);
while (si != s.begin() && getcnt(*(--si), qs[i].bj) == cnt2);
if (si != s.begin()) ++si;
else if (getcnt(*(si), qs[i].bj) != cnt2) ++si;
qs[i].ans = *si;
}
else
{
cnt2 = getcnt(*si, qs[i].bj);
cnt1 = getcnt(*(--si), qs[i].bj);
if (cnt2 > cnt1)
{
++si;
qs[i].ans = *si;
}
else
{
while (si != s.begin() && getcnt(*(--si), qs[i].bj) == cnt1);
if (si != s.begin()) ++si;
else if (getcnt(*(si), qs[i].bj) != cnt1) ++si;
qs[i].ans = *si;
}
}
}
sort(qs + 1, qs + 1 + q, cmp2);
for (i = 1; i <= q; ++i) cout<
You are given two points PP and QQ and an opaque sphere in a three-dimensional space. The point PP is not moving, while QQ is moving in a straight line with constant velocity. You are also given a direction vector dd with the following meaning: the position of QQ at time ttis Q(t)=Q(0)+d⋅tQ(t)=Q(0)+d⋅t, where Q(0)Q(0) is the initial position of QQ.
It is guaranteed that QQ is not visible from PP initially (at time t=0t=0). It is also guaranteed that PP and QQ do not touch the sphere at any time.
Find the smallest positive time tvtv when QQ is visible from PP, i.e. when the line segment connecting points PP and QQ does not intersect the sphere.
For each test case, print a single line containing one real number — the time tvtv. Your answer will be considered correct if its absolute or relative error does not exceed 10−610−6. It is guaranteed that tvtv exists and does not exceed 109109.
Subtask #1 (25 points): Pz=Qz=dz=cz=0Pz=Qz=dz=cz=0
Subtask #2 (75 points): original constraints
1
3 0 0 -10 -10 0 0 10 0 0 -3 0 3
1.0000000000
【分析】脑补一下便可得知当某一时刻PQ相见时,之后的时刻PQ都相见。所以直接二分时间,PQ与圆心的距离大于半径即视为相见。
【代码】
#include
#include
using namespace std;
int Px, Py, Pz, Qx, Qy, Qz, dx, dy, dz, cx, cy, cz, cr;
long double l2;
bool cmp(long double l, long double r)
{
if (r - l > 0.0000001) return 1;
return 0;
}
long double co(long double m1, long double n1, long double p1, long double m2, long double n2, long double p2)
{
return abs(m1 * m2 + n1 * n2 + p1 * p2) / sqrt(m1 * m1 + n1 * n1 + p1 * p1) / sqrt(m2 * m2 + n2 * n2 + p2 * p2);
}
long double si(long double m1, long double n1, long double p1, long double m2, long double n2, long double p2)
{
long double c = co(m1, n1, p1, m2, n2, p2);
return sqrt(1 - c * c);
}
long double mc(long double x, long double y, long double z)
{
return sqrt(x * x + y * y + z * z);
}
long double find(long double l, long double r)
{
long double mid;
long double nx, ny, nz, m, n, p, d, m1, n1, p1, l1;
m1 = cx - Px;
n1 = cy - Py;
p1 = cz - Pz;
l2 = mc(m1, n1, p1);
while (cmp(l, r))
{
mid = (l + r) / 2;
nx = Qx + mid * dx;
ny = Qy + mid * dy;
nz = Qz + mid * dz;
m = nx - Px;
n = ny - Py;
p = nz - Pz;
l1 = mc(m, n, p);
d = l2 * si(m, n, p, m1, n1, p1);
if (d > cr) r = mid;
else l = mid;
}
return l;
}
int main()
{
int T;
long double ans;
scanf("%d", &T);
while (T--)
{
scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d", &Px, &Py, &Pz, &Qx, &Qy, &Qz, &dx, &dy, &dz, &cx, &cy, &cz, &cr);
ans = find(0, 1000000000);
printf("%Lf\n", ans);
}
return 0;
}
Chef Go has planted a flower field — a grid with nn rows and mm columns. In each cell of this grid, a single flower is planted; let's denote the type of the flower planted in cell (i,j)(i,j)by ai,jai,j.
Today, Chef Go is going to make a new menu with two dishes: Tom Yum Goong and Tom Kha Kai. He needs to pick as many flowers as possible to decorate the dishes and make them look attractive. Each dish can only be decorated with flowers of a single type, so he can only pick flowers of one type or two different types. Also, Chef Go wants the flowers he picks to form one connected area, so that he can finish his job quickly. A connected area is a set of cells such that we can move from any cell to any other cell in this set by only moving between side-adjacent cells from the set.
Help Chef Go find the size of the largest connected area in his flower field which contains at most two types of flowers.
Print a single line containing one integer — the maximum number of flowers that can be picked.
Subtask #1 (20 points):
Subtask #2 (20 points):
Subtask #3 (60 points): original constraints
4 5
1 1 2 3 1
3 1 2 5 2
5 2 1 5 6
1 3 1 2 1
10
One connected area with maximum size consists of the following flowers (flowers marked by dots are not picked):
1 1 2 . .
. 1 2 . .
. 2 1 . .
. . 1 2 1
【分析】不会。但是每次提交可以看到每个点的得分情况。然后就乱搞+卡时水过去了。
【代码】
#include
#include
#include
#include
using namespace std;
int a[2100][2100], ans, n, m, ta, tot;
bool b[2100][2100], flag[2100][2100];
int he[4100000], y[16100000], totb, z[16100000], cnt[4100000];
set s;
void dfs(int x, int y, int c1, int c2)
{
++tot;
b[x][y] = 1;
if (x > 1 && !b[x - 1][y] && (c1 == a[x - 1][y] || c2 == a[x - 1][y]) ) dfs(x - 1, y, c1, c2);
if (x < n && !b[x + 1][y] && (c1 == a[x + 1][y] || c2 == a[x + 1][y]) ) dfs(x + 1, y, c1, c2);
if (y > 1 && !b[x][y - 1] && (c1 == a[x][y - 1] || c2 == a[x][y - 1]) ) dfs(x, y - 1, c1, c2);
if (y < m && !b[x][y + 1] && (c1 == a[x][y + 1] || c2 == a[x][y + 1]) ) dfs(x, y + 1, c1, c2);
}
void dfs1(int x, int y)
{
flag[x][y] = 1;
if (x > 1 && a[x - 1][y] == a[x][y] && !flag[x - 1][y]) dfs1(x - 1, y);
if (x < n && a[x + 1][y] == a[x][y] && !flag[x + 1][y]) dfs1(x + 1, y);
if (y > 1 && a[x][y - 1] == a[x][y] && !flag[x][y - 1]) dfs1(x, y - 1);
if (y < m && a[x][y + 1] == a[x][y] && !flag[x][y + 1]) dfs1(x, y + 1);
if (x > 1 && a[x - 1][y] != a[x][y]) s.insert(a[x - 1][y]);
if (x < n && a[x + 1][y] != a[x][y]) s.insert(a[x + 1][y]);
if (y > 1 && a[x][y - 1] != a[x][y]) s.insert(a[x][y - 1]);
if (y < m && a[x][y + 1] != a[x][y]) s.insert(a[x][y + 1]);
}
void mem(int x, int y)
{
b[x][y] = 0;
if (b[x - 1][y]) mem(x - 1, y);
if (b[x + 1][y]) mem(x + 1, y);
if (b[x][y + 1]) mem(x, y + 1);
if (b[x][y - 1]) mem(x, y - 1);
}
int main()
{
clock_t start, end;
bool plan = 0;
start = clock();
int i, j, fans = 0;
set::iterator si;
scanf("%d%d", &n, &m);
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j) scanf("%d", &a[i][j]);
for (i = 1; i <= n; ++i)
{
for (j = 1; j <= m; ++j)
if (!flag[i][j])
{
end = clock();
if ((double)(end - start) / CLOCKS_PER_SEC > 3.3)
{
plan = 1;
break;
}
ans = 0;
s.clear();
dfs1(i, j);
for (si = s.begin(); si != s.end(); si++)
{
tot = 0;
dfs(i, j, a[i][j], *si);
// printf("%d %d\n", a[i][j], *si);
if (tot > ans) ans = tot;
mem(i, j);
si++;
if (si == s.end()) break;
}
tot = 0;
dfs(i, j, a[i][j], 0);
if (tot > ans) ans = tot;
mem(i, j);
if (ans > fans) fans = ans;
}
if (plan) break;
}
if (plan)
{
memset(flag, 0, sizeof(flag));
memset(b, 0, sizeof(b));
fans = 0;
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j)
if (!flag[i][j])
{
ans = 0;
s.clear();
dfs1(i, j);
for (si = s.begin(); si != s.end(); si++)
{
tot = 0;
dfs(i, j, a[i][j], *si);
// printf("%d %d\n", a[i][j], *si);
if (tot > ans) ans = tot;
//mem(i, j);
si++;
if (si == s.end()) break;
}
tot = 0;
dfs(i, j, a[i][j], 0);
if (tot > ans) ans = tot;
//mem(i, j);
if (ans > fans) fans = ans;
}
}
printf("%d", fans);
return 0;
}