2018CCPC吉林赛区(重现赛)部分题解
The Fool
Problem Description
The Fool is numbered 0 – the number of unlimited potential –and therefore does not have a specific place in the sequence of the Tarot cards. The Fool can be placed either at the beginning of the Major Arcana or at the end. The Major Arcana is often considered as the Fool’s journey through life and as such, he is
ever present and therefore needs no number.
Given n ∈ N+, print the parity of
∑i=1N [ni],
where [x] = max a (a∈Z,a≤x)
Input
The first line of the input contains one integer T ≤ 100, denoting the number of testcases. Then T testcases follow.
In each of the T testcases, there is a positive number n ≤ 109.
Output
For each testcase, print a single line starting with “Case i : ”(i indicates the case number) and then “even” or “odd”, separated with a single space.
Sample Input
3
1
10000
100000000
Sample Output
Case 1: odd
Case 2: even
Case 3: even
Sample Output
Case 1: Today 3:00 AM
Case 2: Tomorrow 12:00 AM
解题思路:
找规律,3个odd,然后5个even,然后7个odd......等差数列搞一搞
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e3 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int main()
{
int n;
scanf("%d", &n);
for (int Case = 1; Case <= n; Case++)
{
bool flag = false;
int t;
scanf("%d", &t);
for (int i = 1; i <= sqrt(t); i++)
if (i * i + 2 * i < t && (i + 1) * (i + 1) + 2 * (i + 1) >= t)
{
if (i & 1)
flag = true;
else
flag = false;
break;
}
if (!flag)
printf("Case %d: odd\n", Case);
else
printf("Case %d: even\n", Case);
}
return 0;
}
The World
Problem Description
The World can indicate world travel, particularly on a large scale. You may be lucky enough to be embarking on a six-month overseas trip, or are working, studying or living overseas for an extended period of time. Similarly, this card reinforces Universal understanding and global awareness, and you will have a new appreciation for people and cultures from across the world.
Across the world there are various time zones, leading to time differences. Here you are informed of several famous capitals and their corresponding time zones.
Beijing - China - UTC + 8 (China Standard Time)
Washington - United States - UTC - 5 (Eastern Standard Time)
London - United Kingdom - UTC (Greenwich Mean Time)
Moscow - Russia - UTC + 3 (Moscow Time)
Given the local time of a city, you are expected to calculate the date and local time of another specific city among the above capitals.
Input
The first line of input contains a single integer T ≤ 1000 indicating the number of testcases.
Each testcase consists of three lines. The first line is in the form of “hour:minute AM/PM” (1 ≤ hour ≤ 12, 00 ≤ minute ≤ 59) indicating the local time. Next two lines contain two strings s1, s2. s1 is the name of city corresponding to the given time, while s2 indicates the city you are expected to calculate the local time.
Output
For each testcase, begin with “Case i:”, where i indicate the case number, and then output a single line in the following format“Yesterday/Today/Tomorrow hour:minute AM/PM”, separated by spaces. The first word describes the corresponding date.
Sample Input
2
12:00 AM
London
Moscow
4:00 PM
London
Beijing
Sample Output
Case 1: Today 3:00 AM
Case 2: Tomorrow 12:00 AM
解题思路:
将今天的零点作为起点就简易很多
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e3 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int main()
{
int t;
scanf("%d", &t);
map<string, int> mp;
mp["Beijing"] = 8;
mp["Washington"] = -5;
mp["London"] = 0;
mp["Moscow"] = 3;
for (int Case = 1; Case <= t; Case++)
{
int flag = 0; //0今 1明 -1昨天
int h, m;
string ap;
scanf("%d:%d", &h, &m);
cin >> ap;
string from, to;
cin >> from >> to;
int temp = mp[to] - mp[from];
if (h == 12)
h = 0;
if (ap == "PM")
h += 12;
h += temp;
if (h < 0)
{
flag = -1;
h = 24 + h;
}
else if (h >= 24)
{
flag = 1;
h -= 24;
}
if (h >= 12)
{
h -= 12;
ap = "PM";
}
else
ap = "AM";
if (h == 0)
h += 12;
printf("Case %d: ", Case);
if (flag == 0)
cout << "Today ";
else if (flag == 1)
cout << "Tomorrow ";
else
cout << "Yesterday ";
printf("%d:%02d ", h, m);
cout << ap << endl;
}
return 0;
}
Justice
Problem Description
The World can indicate world travel, particularly on a large scale. You may be lucky enough to be embarking on a six-month overseas trip, or are working, studying or living overseas for an extended period of time. Similarly, this card reinforces Universal understanding and global awareness, and you will have a new appreciation for people and cultures from across the world.
Across the world there are various time zones, leading to time differences. Here you are informed of several famous capitals and their corresponding time zones.
Beijing - China - UTC + 8 (China Standard Time)
Washington - United States - UTC - 5 (Eastern Standard Time)
London - United Kingdom - UTC (Greenwich Mean Time)
Moscow - Russia - UTC + 3 (Moscow Time)
Given the local time of a city, you are expected to calculate the date and local time of another specific city among the above capitals.
Input
In the first line of the input there is a positive integer T (1 ≤ T ≤ 2000), indicating there are T testcases.
In the first line of each of the T testcases, there is a positive integer n (1 ≤ n ≤ 105, ∑n ≤ 7 × 105), indicating there are n weights on the table.
In the next line, there are n integers ki (1 ≤ ki ≤ 109), indicating the number carved on each weight.
Output
For each testcase, first print Case i: ANSWER in one line, i indicating the case number starting from 1 and ANSWER should be either YES or NO, indicating whether or not it is possible to divide the weights. Pay attention to the space between : and ANSWER.
If it’s possible, you should continue to output the dividing solution by print a 0/1 string of length n in the next line. The i-th character in the string indicating whether you choose to put the i-th weight in group 0 or group 1.
Sample Input
3
3
2 2 2
3
2 2 1
2
1 1
Sample Output
Case 1: NO
Case 2: YES
001
Case 3: YES
10
解题思路:
两个4可凑一个3,不断往上凑凑出两个1,凑的过程过标记下就成
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e5 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int vis[MAXN];
PII a[MAXN];
int main()
{
int t;
scanf("%d", &t);
for (int Case = 1; Case <= t; Case++)
{
memset(vis, 0, sizeof(vis));
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i].first), a[i].second = i;
sort(a + 1, a + 1 + n);
int pre = 1;
int cnt1 = 1, cnt2 = 1;
bool flag = true;
for (int i = 1; i <= n; i++)
{
while (pre < a[i].first && cnt1 + cnt2 <= n - i + 1)
{
cnt1 <<= 1;
cnt2 <<= 1;
pre++;
}
if (cnt1 + cnt2 > n - i + 1)
{
flag = false;
break;
}
if (cnt1)
{
cnt1--;
vis[a[i].second] = 1;
}
else
cnt2--;
if (!cnt1 && !cnt2)
break;
}
printf("Case %d: ", Case);
if (flag)
{
printf("YES\n");
for (int i = 1; i <= n; i++)
printf("%d", vis[i]);
printf("\n");
}
else
printf("NO\n");
}
return 0;
}
The Moon
Problem Description
The Moon card shows a large, full moon in the night’s sky, positioned between two large towers. The Moon is a symbol of intuition, dreams, and the unconscious. The light of the moon is dim, compared to the sun, and only vaguely illuminates the path to higher consciousness which winds between the two towers.
Random Six is a FPS game made by VBI(Various Bug Institution). There is a gift named "Beta Pack". Mr. K wants to get a beta pack. Here is the rule.
Step 0. Let initial chance rate q = 2%.
Step 1. Player plays a round of the game with winning rate p.
Step 2. If the player wins, then will go to Step 3 else go to Step 4.
Step 3. Player gets a beta pack with probability q. If he doesn’t get it, let q = min(100%, q + 2%) and he will go to Step 1.
Step 4. Let q = min(100%, q + 1.5%) and goto Step 1.
Mr. K has winning rate p% , he wants to know what’s the expected number of rounds before he needs to play.
Input
The first line contains testcase number T (T ≤ 100). For each testcase the first line contains an integer p (1 ≤ p ≤ 100).
Output
For each testcase print Case i : and then print the answer in one line, with absolute or relative error not exceeding 106.
Sample Input
2
50
100
Sample Output
Case 1: 12.9933758002
Case 2: 8.5431270393
解题思路:
倒着dp回去,每次记忆化搜索出期望
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e6 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
double dp[110][1010]; /* 概率p在概率q情况下对应的期望 */
int a[MAXN];
double dfs(int p, int q)
{
if (q >= 1000)
return 100.0 / p;
if (dp[p][q] != -1)
return dp[p][q];
dp[p][q] = 1.0 + (p / 100.0) * (1.0 - q / 1000.0) * dfs(p, q + 20) + ((100 - p) / 100.0) * dfs(p, q + 15);
return dp[p][q];
}
int main()
{
int t;
scanf("%d", &t);
for (int i = 1; i <= 100; i++)
for (int j = 1; j <= 1000; j++)
dp[i][j] = -1;
for (int Case = 1; Case <= t; Case++)
{
int n;
scanf("%d", &n);
printf("Case %d: %.10f\n", Case, dfs(n, 20));
}
return 0;
}
The Tower
Problem Description
The Tower shows a tall tower perched on the top of a rocky mountain. Lightning strikes, setting the building alight, and two people leap from the windows, head first and arms outstretched. It is a scene of chaos and destruction.
There is a cone tower with base center at (0, 0, 0), base radius r and apex (0, 0, h). At time 0 , a point located at (x0, y0, z0) with velocity (vx, vy, vz). What time will they collide? Here is the cone tower.
Input
The first line contains testcase number T (T ≤ 1000), For each testcase the first line contains spaceseparated real numbers r and h (1 ≤ r, h ≤ 1000) — the base radius and the cone height correspondingly.
For each testcase the second line contains three real numbers x0, y0, z0 (0 ≤ |x0|, |y0|, z0 ≤ 1000). For each testcase the third line contains three real numbers vx, vy, vz (1 ≤ v2x + v2y + v2z ≤ 3 × 106). It is guaranteed that at time 0 the point is outside the cone and they will always collide.
Output
For each testcase print Case i : and then print the answer in one line, with absolute or relative error not exceeding 10−6
Sample Input
2
1 2
1 1 1
-1.5 -1.5 -0.5
1 1
1 1 1
-1 -1 -1
Sample Output
Case 1: 0.3855293381
Case 2: 0.5857864376
解题思路:
由r,h得出圆锥方程,当撞击发生时,(x,y,z)=(x0,y0,z0)+t(vx,vy,vz)代入圆锥方程求解t
注意碰撞必然发生在z在0~h的区间内,同时圆锥底部也可能发生碰撞,取Min
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e6 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
double r, h, x, y, z, vx, vy, vz;
bool judge(int t) /* 判断能不能撞到底面 */
{
int tx = x + vx * t;
int ty = y + vy * t;
if (tx * tx + ty * ty <= r * r)
return true;
return false;
}
int main()
{
int t;
scanf("%d", &t);
for (int Case = 1; Case <= t; Case++)
{
scanf("%lf%lf", &r, &h);
scanf("%lf%lf%lf", &x, &y, &z);
scanf("%lf%lf%lf", &vx, &vy, &vz);
double a = vx * vx + vy * vy - vz * vz * r * r / (h * h);
double b = 2 * vx * x + 2 * vy * y - (2 * z * vz - 2 * h * vz) * r * r / (h * h);
double c = x * x + y * y + (2 * h * r * r * z - r * r * z * z) / (h * h) - r * r;
double t1 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a), t2 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
double t3 = z / vz;
double ans = inf;
if (t3 >= 0 && judge(t3))
ans = min(ans, t3);
if (t1 >= 0 && z + vz * t1 >= 0 && z + vz * t1 <= h)
ans = min(ans, t1);
if (t2 >= 0 && z + vz * t2 >= 0 && z + vz * t2 <= h)
ans = min(ans, t2);
printf("Case %d: %.10f\n", Case, ans);
}
return 0;
}
The Hermit
Problem Description
The Hermit stands alone on the top of a mountain with a lantern in his hand. The snow-capped mountain range symbolises the Hermit’s spiritual achievement, growth and accomplishment. He has chosen this path of self-discovery and, as a result, has reached a heighted state of awareness
dhh loves to listen to radio. There are N radio stations on a number axis, and the i-th station is located at xi = i. The broadcasting scope of the i-th station is radi , which means stations in the interval [i - radi + 1, i + radi - 1] can receive the signal from the i-th station. For some unknown reason, the left boundary that can receive the i-th station’s signal is non-descending, which meansi i - radi + 1 ≤ i + 1 - radi+1 + 1.
Now dhh wants to listen to the radio from station i, and he finds that the station k, satisfying both of the following conditions, can receive perfect signal from the station i:
k < i and station k can receive station i’s signal.
There exists another station j(k ≤ j < i) such that station k and i can both receive the signal from station j and the distance between station k and j is greater than or equal to the distance between station j and i.
Now dhh wonders for each station i, how many stations can receive the perfect signal from station i.
Input
The first line of the input contains one integer T ≤ 20, denoting the number of testcases. Then T testcases follow. For each testcase:
The first line contains one positve integer N.
The second line contains N positive integers rad1, rad2, ... , radN .
It’s guaranteed that 1 ≤ N ≤ 106 ,i - radi + 1 ≥ 1 and i + radi - 1 ≤ N
Output
For the k-th testcase, output “Case k: ans” in one line, where ans represents the xor result of answer for each radio station i.
xor is a bitwise operation, which takes two bit patterns of equal length and performs the logical exclusive OR operation on each pair of corresponding bits. The result in each position is 1 if only the first bit is 1 or only the second bit is 1, but will be 0 if both are 0 or both are 1. In this we perform the comparison
of two bits, being 1 if the two bits are different, and 0 if they are the same.
Sample Input
2
7
1 2 3 4 3 2 1
10
1 1 2 3 4 4 3 2 2 1
Sample Output
Case 1: 2
Case 2: 0
解题思路:
盲猜结论
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e6 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int a[MAXN];
int main()
{
int t;
scanf("%d", &t);
for (int Case = 1; Case <= t; Case++)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
int ans = 0;
for (int i = 2; i < n; i++)
if (a[i] >= 2)
ans ^= a[i] - 2;
printf("Case %d: %d\n",Case, ans);
}
return 0;
}
Strength
Problem Description
Strength gives you the confidence within yourself to overcome any fears, challenges or doubts. Feel the fear and do it anyway! If you have been going through a rough time and feel burnt out or stressed, the Strength card encourages you to find the strength within yourself and keep going. You have got what it takes to see this situation through to its eventual end. You might also feel compelled to hold space for someone else who is going through a difficult period and needs your strength and support.
Alice and Bob are playing “Yu-Gi-Oh!”, a famous turn-based trading card game, in which two players perform their turns alternatively. After several turns, Alice and Bob have many monsters respectively.
Alice has n and Bob has m monsters under their own control. Each monster’s strength is measured by a non-negative integer si . To be specific, the larger si is, the more power the monster has.
During each turn, for every single monster under control, the player can give a command to it at most once, driving it to battle with an enemy monster (given that opposite player has no monsters as a shield, the monster can directly attack him).
Additionally, the process of the battle is also quite simple. When two monsters battle with each other, the stronger one (i.e. the one with larger si) will overwhelm the other and destroy it and the winner’s strength will remain unchanged. Meanwhile, the difference of their strength will produce equivalent damage to the player who loses the battle. If the player is directly attacked by a monster, he will suffer from the damage equal to the monster’s strength. Notice that when two monsters have the same strength, both of them will vanish and no damage will be dealt.
Right now it is Alice’s turn to play, having known the strength of all monsters, she wants to calculate the maximal damage she can deal towards Bob in one turn. Unfortunately, Bob has great foresight and is well-prepared for the upcoming attack. Bob has converted several of his monsters into defense position,
in which even if the monster is destroyed, he wouldn’t get any damage.
Now you are informed of the strength of all the monsters and whether it is in defense position for each Bob’s monster, you are expected to figure out the maximal damage that could be dealt in this turn.
Input
The first line contains a single integer T ≤ 20 indicating the number of test cases.
For each test case, the first line includes two integer 0 ≤ n, m ≤ 100000, representing the number of monsters owned by Alice and Bob.
In next three lines, the first two lines include n and m integers 0 ≤ si ≤ 109 indicating the strength of the i-th monster, separated by spaces. The last line contains m integers 0 or 1 indicating the position of Bob’s i-th monsters.In other words, 0 represents the normal position and 1 represents the defense position.
Output
For the ith test, output a single line in beginning of “Case i:”, followed by an integer indicating the answer, separated by a single space.
Sample Input
2
4 2
10 10 10 20
5 15
0 1
4 2
10 10 10 20
5 25
0 1
Sample Output
Case 1: 25
Case 2: 15
解题思路:
贪心模拟,优先高攻打对面的低攻攻击怪,如果打完了攻击怪再试试能不能打完防御怪,再直接走脸,或者优先取最接近的打掉所有防御和攻击怪,然后全走脸,两种策略取max
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e5 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int a[MAXN];
int b0[MAXN], b1[MAXN], b[MAXN];
int vis[MAXN];
int main()
{
int t;
scanf("%d", &t);
for (int Case = 1; Case <= t; Case++)
{
memset(vis, 0, sizeof(vis));
int cnt1 = 0, cnt2 = 0;
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
for (int j = 0; j < m; j++)
scanf("%d", &b[j]);
for (int j = 0; j < m; j++)
{
int t;
scanf("%d", &t);
if (t)
b1[cnt2++] = b[j]; /* 防御 */
else
b0[cnt1++] = b[j]; /* 攻击 */
}
int ans1 = 0, ans2 = 0;
sort(a, a + n);
sort(b0, b0 + cnt1);
sort(b1, b1 + cnt2);
/*先尝试一下能不能打爆所有防御的*/
int posa = 0, posb = 0;
while (posa < n && posb < cnt2)
{
if (b1[posb] <= a[posa])
{
vis[posa] = 1;
posa++;
posb++;
}
else
posa++;
}
if (posb >= cnt2) /* 我把防守的打完了! */
{
/* 试试能不能打完攻击的 */
posa = 0, posb = 0;
while (posa < n && posb < cnt1)
{
if (!vis[posa] && b0[posb] <= a[posa])
{
vis[posa] = 1;
ans1 += a[posa] - b0[posb];
posa++;
posb++;
}
else if (vis[posa])
posa++;
}
if (posb >= cnt1) /* 打完了攻击的 */
{
for (int i = 0; i < n; i++)
if (!vis[i])
ans1 += a[i];
}
else
ans1 = 0;
}
else /* 打不过防守的 */
{
/* 尝试一下暴打攻击的 */
posa = n - 1, posb = 0;
while (posa >= 0 && posb < cnt1)
{
if (a[posa] >= b0[posb])
{
ans2 += a[posa] - b0[posb];
posa--;
posb++;
}
else
break;
}
if (posb < cnt1)
ans2 = 0;
}
printf("Case %d: %d\n", Case, max(ans1, ans2));
}
return 0;
}