今日头条杯2018湖北省大学生程序设计竞赛(网络赛)
A. GSS and CQ
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
CQCQCQ this is BG6TOE Bravo Golf Six Tango Oscar Echo BG6TOE
In amateur radio communication, every ham has his or her call sign, which is a sequence (the length of which is no more than 6) of letters and digits, for example, GSS’s call sign is BG6TOE, where B means HAM from Mainland China, and G means the type of radio station, and 6 means Hubei Province, Anhui Province or Jiangxi Province, then TOE is the suffix, in some cases (e.g. just call someone who is on the channel), call TOE instead BG6TOE is enough.
To start a call, you cal use CQ, the correct way to call is to: Say CQ for three times, e.g. CQCQCQ and then Your call sign, e.g. BG6TOE, for three times, the second time should use NATO Alphabet.
Other parts are optional, for a typical CQ call, one may say:
CQCQCQ this is
Given a list of call signs, your task is to determine what thay would say in the format above.
A : Alfa | J : Juliett | S : Sierra | 1 : One
B : Bravo | K : Kilo | T : Tango | 2 : Two
C : Charlie | L : Lima | U : Uniform | 3 : Three
D : Delta | M : Mike | V : Victor | 4 : Four
E : Echo | N : November | W : Whiskey | 5 : Five
F : Foxtrot | O : Oscar | X : Xray | 6 : Six
G : Golf | P : Papa | Y : Yankee | 7 : Seven
H : Hotel | Q : Quebec | Z : Zulu | 8 : Eight
I : India | R : Romeo | 0 : Zero | 9 : Nine
The pure text version of the table above can be found at the link below:
http://acm.whu.edu.cn/upload/2018/whupc/nato.txt
Input
Input contains multiple lines, please process to the end of input.
Each line contains a valid call sign.
Output
For each line of input, output one line with the CQ call in the
description above.
Example
input
BG6TOE
bg6rr
bA1Aa
m0xpd
output
CQCQCQ this is BG6TOE Bravo Golf Six Tango Oscar Echo BG6TOE
CQCQCQ this is BG6RR Bravo Golf Six Romeo Romeo BG6RR
CQCQCQ this is BA1AA Bravo Alfa One Alfa Alfa BA1AA
CQCQCQ this is M0XPD Mike Zero Xray Papa Delta M0XPD
Note
You should note that both input and output are Case Insensitive
#include <bits/stdc++.h>
using namespace std;
unordered_map<char, string> nato;
int main()
{
nato['A'] = "Alfa";
nato['B'] = "Bravo";
nato['C'] = "Charlie";
nato['D'] = "Delta";
nato['E'] = "Echo";
nato['F'] = "Foxtrot";
nato['G'] = "Golf";
nato['H'] = "Hotel";
nato['I'] = "India";
nato['J'] = "Juliett";
nato['K'] = "Kilo";
nato['L'] = "Lima";
nato['M'] = "Mike";
nato['N'] = "November";
nato['O'] = "Oscar";
nato['P'] = "Papa";
nato['Q'] = "Quebec";
nato['R'] = "Romeo";
nato['S'] = "Sierra";
nato['T'] = "Tango";
nato['U'] = "Uniform";
nato['V'] = "Victor";
nato['W'] = "Whiskey";
nato['X'] = "Xray";
nato['Y'] = "Yankee";
nato['Z'] = "Zulu";
nato['0'] = "Zero";
nato['1'] = "One";
nato['2'] = "Two";
nato['3'] = "Three";
nato['4'] = "Four";
nato['5'] = "Five";
nato['6'] = "Six";
nato['7'] = "Seven";
nato['8'] = "Eight";
nato['9'] = "Nine";
char buf[20];
while (~scanf("%s", buf))
{
for (int i = 0; buf[i]; i++) {
if (buf[i] >= 'a' && buf[i] <= 'z') {
buf[i] = buf[i] - 'a' + 'A';
}
}
printf("CQCQCQ this is %s", buf);
for (int i = 0; buf[i]; i++) {
printf(" %s", nato[buf[i]].c_str());
}
printf(" %s\n", buf);
}
return 0;
}
B. GSS and Interesting Sculpture
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
GSS is painting an strange sculpture, the sculpture contests of two balls and they may intersect. Your task is to calculate the area of the surface of the sculpture.
Input
Input contains multiple cases, please process to the end of input.
For each line, there are three integers, R, r, L, R and r the radius of the two balls, (L) is the distance of the center of two balls.
0 < R, r, L ≤ 100, |R - r| < L ≤ |R + r|
Output
For each input, output one line with the answer, the area of the surface of the sculpture. Let the standard answer be (a), and your answer be (b), your answer will be considered as correct if and only if .
Example
inputCopy
3 4 5
3 3 3
1 2 3
outputCopy
271.433605270158
169.646003293849
62.831853071796
然后取的余角公式变为
再利用余弦公式
可以求出结果。
#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
double sqr(double x) {return x * x;}
double calc_area(double t1, double t2)
{
return cos(t1) - cos(t2);
}
double sol(double r, double R, double L)
{
double x1 = (sqr(R) - sqr(r) + sqr(L)) / (2 * R * L);
double x2 = (sqr(r) - sqr(R) + sqr(L)) / (2 * r * L);
double area1 = x1 + 1;
double area2 = x2 + 1;
return 2 * pi * (area1 * sqr(R) + area2 * sqr(r));
}
int main()
{
int r, R, L;
while (~scanf("%d%d%d", &r, &R, &L))
printf("%.12f\n", sol(r, R, L));
return 0;
}
C. GSS and Bubble Sort
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
Do you remember the problem “Time Limit Exceeded” last year? Here is the code GSS wrote in that problem.
#include <stdio.h>
int main() {
int n;
int *vec;
scanf(" vec = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
int t;
scanf("%d", &t);
vec[i] = t;
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n - 1; j++)
if (vec[j] > vec[j+1])
swap(vec[j], vec[j+1]);
/* some other code takes O(1) time */
return 0;
}
As you are GSS’s team mate, your task is to calculate the expected time the code will run with an input of size (n), ((0< n < 10^9)). The time is measured by how many times the function swap is called. You should note that the input is a permutation of ({1,2, …, n}) in the original problem.
Input
Input contains multiple (about 1000) test cases, please process to the end of input.
Each test cases contains an integer (n) as described above.
Output
For each test case, output one line with the answer.
If your answer is (p / q), then you should output p × q109 + 5 module 1000000007 ((10^9+7)).
Example
inputCopy
1
2
outputCopy
0
500000004
Note
In the second sample, there are two possible input ({1,2}) and ({2,1}), so the expected time the function swap is called is ((0 + 1) / 2 = 1/2), and 1 × 2109 + 5 module (10^9+7) is (500000004).
可以找规律,最后结果为n(n-1)/4
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define MOD 1000000007
LL pow_mod(LL a,LL b,LL mod)
{
LL ret=1;
while(b)
{
if(b&1)
{
ret=(ret*a)%mod;
}
a=(a*a)%mod;
b>>=1;
}
return ret;
}
int main()
{
LL n;
while(cin>>n)
{
LL ans=(n*(n-1))%MOD;
ans=ans*pow_mod(4,MOD-2,MOD)%MOD;
cout<<ans<<endl;
}
return 0;
}
D. GSS and Version Control
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
GSS has invented a brand new version control system, called Gss’s Interesting Theory, or Git in short. It support two basic operations:
Append a new commit to current version (thus made a new version)
Revert the state of the project of the (i)-th day.
As GSS just started a brand-new project, it is day 0 now. Every other day, GSS would upload his work (one of the two operations above) to the repository of the project.
The version control system would calculate the hash of the whole project. And the checksum of the project is the bitwise exclusive or (xor) of all the checksum of commits which is valid (not reverted) at one version.
Your task is to calculate the hash of the whole project after GSS’s commit.
Input
The first line of input is a single number (n), the number of days that GSS works on the project.
Then (n) line follows, the i-th line consists of a string and an integer in the format below:
commit x, append a new commit to the current version, and (x) is the checksum of the commit, 0 ≤ x ≤ 109.
checkout k, revert the state of the project to the (k)-th day, 0 ≤ k < i.
Output
For each operation, output the hash of the project after the operation.
Example
inputCopy
7
commit 1
commit 2
checkout 1
checkout 0
commit 4
checkout 2
checkout 5
outputCopy
1
3
1
0
4
3
4
这道题应该是卡IO,把输入改成scanf和输出改成printf
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000000 + 5;
int rt[maxn], vl[maxn];
int main()
{
int n;
char buf[10];
int x;
int cur = 0, nd = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%s%d", buf, &x);
if (buf[1] == 'o') // commit
{
rt[i] = nd;
vl[i] = x ^ vl[i - 1];
} else { // checkout
vl[i] = vl[x];
}
printf("%d\n", vl[i]);
}
return 0;
}
E. Jump A Jump
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
There’s a very popular game called jump a jump recently.In order to get good marks, many people spend a lot of time in this game.Wei is the master of jump a jump,he can easily get a very high score every time.
Recently he discovered that because of his muscle memory,he could not fully control his game score.
Now he wants you to help him figure out the nearest score that he can get from his desired score.
Every time he jumps, he chooses one from m distances,he can jump until he wants to end,and he can also use every distance any times.
Input
The first line has a number n(0 < n ≤ 1015) to indicate the score he desired.
The next line has a number m(0 < m ≤ 2000), which indicates how many choices each step has.
The last line has m integers bi(0 < bi ≤ 5000) representing the ith distances.
Output
Output is the absolute value of the difference between the nearest score he can get and his desired score.
Example
inputCopy
11
3
5 7 8
outputCopy
1
Note
In the example,
He can jump 5 + 7 = 12, 12 - 11 = 1.
He can also jump two times 5,and 2*5 = 10, 11 - 10 = 1.
这道题题解是用取最小b[i]模,然后最短路求解,但是还是不太理解
现在先空着,后面等理解了再来补坑。。。。。。。。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const long long maxn = 5010;
const long long INF = 0x3f3f3f3f3f3f3f3f;
long long vis[maxn];
long long dis[maxn];
long long n,m,mod;
long long b[maxn];
struct node
{
long long x,d;
node();
node(long long xx,long long dd){
x = xx;
d = dd;
}
};
vector<node> edge[maxn];
void dijkstra(long long x)
{
long long i,j;
for(i=0;i<mod;i++) vis[i] = 0,dis[i] = INF;
dis[x] = 0;
for(i=0;i<mod;i++){
long long minn = INF;
long long u = 0;
for(j=0;j<mod;j++){
if(!vis[j] && minn > dis[j]){
minn = dis[j];
u = j;
}
}
vis[u] = 1;
for(j=0;j<edge[u].size();j++){
long long v = edge[u][j].x;
if(!vis[v] && (minn + edge[u][j].d) < dis[v])
dis[v] = minn + edge[u][j].d;
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
cin>>n>>m;
mod = maxn;
for(long long i=1; i<=m; i++){
scanf("%d",&b[i]);
mod = min(b[i],mod);
}
for(long long i=0; i<mod; i++){
for(long long j=1; j<=m; j++){
edge[i].push_back(node((b[j]+i)%mod,b[j]));
}
}
dijkstra(0);
long long ans = maxn;
for(long long i=0; i<mod; i++){
if(dis[i] < n){
long long x = (n-dis[i])%mod;
long long y = min(x,mod-x);
ans = min(ans,y);
}
else{
ans = min(ans,dis[i]-n);
}
}
cout<<ans<<endl;
return 0;
}
F. A-maze-ing
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
Long long age, a wise but barbaric king made a plan to convert the arena to a maze so that he could get pleasure from watching his servant running the maze confusedly.
The structure of the arena could be abstracted into a directed connected graph comprised of n (1 ≤ n ≤ 105) nodes and m (1 ≤ m ≤ 2 × 105) edges.
The king had not decided where to set up the starting nodes and the end node.
So the king proposed a requirement.
Whichever two points u, v he chose, there existed a path from one point to the other(a path from u to v or from v to u).
Moreover, the king hoped to improve the difficulty of the game, so the number of nodes in the maze should be as large as possible.
You are only required to output the maximum number of nodes in the maze.
Input
There are two positive integers n and m in the first line.
And then m lines follow, in each line there are two positive integers u and v, describing that an edge from node u to node v.
Output
Just output one integer, the maximum size of the maze.
Example
inputCopy
3 2
1 2
1 3
outputCopy
2
这道题的题解是任意的有向图通过强联通缩点操作可以转换为DAG,所以本题可以经过强联通缩点以后,求DAG的带权最长链。
#include <bits/stdc++.h>
#include <ctime>
using namespace std;
const int N = 1e5 + 8;
int dfn[N], low[N], st[N], belong[N], num[N];
bool instack[N];
vector <int> vec[N], eg[N];
int deg[N], dp[N];
int n, m;
int top, cnt, id;
int tot = 0;
void init()
{
for (int i = 1; i <= n; ++i)
vec[i].clear();
for (int i = 1; i <= m; ++i)
{
int u, v;
scanf("%d %d", &u, &v);
vec[u].push_back(v);
}
}
void tarjan(int u)
{
dfn[u] = low[u] = ++id;
instack[u] = true;
st[++top] = u;
for (auto v : vec[u])
{
if (!dfn[v])
{
tarjan(v);
low[u] = min(low[v], low[u]);
}
else if (instack[v])
low[u] = min(dfn[v], low[u]);
}
if (low[u] == dfn[u])
{
cnt++;
int j;
do
{
num[cnt]++;
j = st[top--];
instack[j] = false;
belong[j] = cnt;
}
while (j != u);
}
}
void rebuild()
{
top = cnt = id = 0;
for (int i = 1; i <= n; ++i)
instack[i] = dfn[i] = num[i] = 0;
for (int i = 1; i <= n; ++i)
if (!dfn[i])
tarjan(i);
for (int i = 1; i <= cnt; ++i)
eg[i].clear();
for (int u = 1; u <= n; ++u)
for (auto v : vec[u])
if (belong[u] != belong[v])
eg[belong[u]].push_back(belong[v]);
}
void solve()
{
static queue <int> Q;
for (int i = 1; i <= cnt; ++i)
dp[i] = deg[i] = 0;
for (int u = 1; u <= cnt; ++u)
for (auto v : eg[u])
deg[v]++;
for (int i = 1; i <= cnt; ++i)
if (deg[i] == 0)
{
Q.push(i);
dp[i] = num[i];
}
while (!Q.empty())
{
int u = Q.front();
Q.pop();
for (auto v : eg[u])
{
deg[v]--;
dp[v] = max(dp[v], dp[u] + num[v]);
if (deg[v] == 0)
Q.push(v);
}
}
int ans = 0;
for (int u = 1; u <= cnt; ++u)
ans = max(ans, dp[u]);
cout << ans << endl;
}
int main()
{
while (~scanf("%d %d", &n, &m))
{
init();
rebuild();
solve();
}
return 0;
}
G. Pretty Derby
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
This is an interactive problem.
There are exactly 25 little ponies, and they want to know who is the fastest and who is the first runner-up (or the second place), so they asked you for help.
You have a field which can hold a race with at most 5 ponies, and you do not have a stopwatch, so you only know who is the the first, second, third, forth and last in a run. The ponies’ speed is so stable that no matter how many runs you make, their rank won’t change.
Please help them with the minimum number of runs!
Input
Let’s number the ponies from 1 to 25. For each run, you should output five numbers x1, x2, x3, x4, x5 in a line separated by spaces, means that you held a race with these five ponies.
Then, you can read a permutation of 1 to 5, the rank of the five ponies in the race.
After you can determine which two ponies runs fastest, output two number, the first and second fastest pony among the 25 ponies, and three zeroes in a line, like 1 2 0 0 0 if you thought that the pony number 1 is the fastest and pony number 2 is the second fastest.
Remember to flush stdout after each line of your output!
Example
inputCopy
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
outputCopy
1 2 3 4 5
1 2 6 7 8
1 2 9 10 11
1 2 12 13 14
1 2 15 16 17
1 2 18 19 20
1 2 21 22 23
1 2 23 24 25
1 2 0 0 0
Note
The example above is just a example interaction, you should not take it seriously.
When you write the solution for the interactive problem it is important to keep in mind that if you output some data it is possible that this data is first placed to some internal buffer and may be not directly transferred to the interactor. In order to avoid such situation you have to use special flush operation each time you output some data. There are these flush operations in standard libraries of almost all languages. For example, in С++ you may use fflush(stdout) or cout < < flush (it depends on what do you use for output data — scanf/printf or cout). In Java you can use method flush for output stream, for example, System.out.flush(). In Python you can use stdout.flush().
Input/output in interactive problems works much slower than in usual problems — try to use scanf/printf instead of cin/cout in C++, BufferedReader/PrintWriter in Java and etc.
本题为交互题,但是可以发现25匹马赛跑取出前两名正解是分为五组分别赛跑,取每组第一名进行赛跑可以得到第一块的马;然后将第一块的马的组的第二名与其他组的第一名进行赛马,可以得到第二快的马。总共7次,不过有些特殊情况6次就能得出答案。
注意: c++中刷新缓存为cin.flush();c语言刷新缓存为fflush(stdout)
#include <bits/stdc++.h>
using namespace std;
int allHorse[6][6];
int sortHorse[6][6];
int paixu;
int headHorse[6];
int secondHorse[6];
int main()
{
int num=1;
for(int i=1;i<=5;i++)
{
for(int j=1;j<=5;j++)
{
allHorse[i][j]=num++;
}
}
int i,j,k;
//先每组进行一次赛马
for(i=1;i<=5;i++)
{
for(j=1;j<=5;j++)
{
printf("%d ",allHorse[i][j]);
}
printf("\n");
fflush(stdout);
for(k=1;k<=5;k++)
{
scanf("%d",&paixu);
sortHorse[i][paixu]=allHorse[i][k];
}
}
//对每组第一名进行一次赛马
int first,second;
for(i=1;i<=5;i++)
{
printf("%d ",sortHorse[i][1]);
}
printf("\n");
fflush(stdout);
for(k=1;k<=5;k++)
{
scanf("%d",&paixu);
headHorse[paixu]=sortHorse[k][1];
if(paixu==1)
first=k;
}
//对头名组的第二名与其他组的头名赛马
for(k=1;k<=5;k++)
{
if(k==first)
{
printf("%d ",sortHorse[k][2]);
secondHorse[k]=sortHorse[k][2];
continue;
}
printf("%d ",sortHorse[k][1]);
secondHorse[k]=sortHorse[k][1];
}
printf("\n");
fflush(stdout);
for(k=1;k<=5;k++)
{
scanf("%d",&paixu);
if(paixu==1)
second=k;
}
printf("%d %d %d %d %d \n",headHorse[1],secondHorse[second],0,0,0);
return 0;
}
H. GSS and OJ Submissions
time limit per test6 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
GSS is holding a large programming contest on the website called EOJ or compileError Online Judge which is the largest programming contest platform in the world. Every day, millians of codes are submitted to the platform.
One day, someone submitted the n-th code (1 ≤ n ≤ 4 × 108), where n is GSS’s lucky number, to celebrate this day, GSS is going to send a huge prize. In this case, he allocated every submission a number in [0, 264) (see the paragraph below), then he generate another number L in [1, n] . The user who submitted the submission with the L-th small number will receive the prize.
GSS allocate numbers to submissions in the following way:
typedef unsigned long long ull;
void allocate(ull A, ull B, ull s0, ull s[])
{
s[0] = s0;
for (int i = 1; i < n; i++) {
s[i] = s[i - 1] * A + B;
}
}
A, B and s0 are generated elsewhere, and 0 ≤ A, B, s0 < 264. And you can assume that A, B and s0 are generated in random.
Special notice: the code above will comsume about 2 seconds or more on judger.
Now, Mingming have collected all numbers allocated to his submissions, and he wants to know weather he will win the prize. But he is too lazy to solve, so he asked you for help, please, tell him the number allocated to the submission which win the prize.
Input
Input contains 5 integers, A, B, L, n, s0.
Output
Output one line with the number —— the number allocated to the submission which win the prize.
Example
inputCopy
5 7 9 11 13
outputCopy
5761717
Note
The numbers allocated to submissions are:
13, 72, 367, 1842, 9217, 46092, 230467, 1152342, 5761717, 28808592, 144042967
it is clear that the ninth one is 5761717.
因为数据范围是4e8,肯定会存不下,所以用到分块的思想。但是还需要注意如果全存下4e8的数据就需要2秒
下面是武大给的标程:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
ull A, B, s0;
inline ull next_random() {
ull ret = s0;
s0 = A * s0 + B;
return ret;
}
vector<ull> v;
#define MX_PART 20
ull divide[MX_PART + 5];
ll cnt[MX_PART + 5];
ll part;
void add_to_part(ull ss) {
cnt[upper_bound(÷[0], ÷[MX_PART], ss) - ÷[0] - 1]++;
}
ull get_kth_2(ull ts0, ll n, ll cn, ll k, ull lb, ull ub)
{
s0 = ts0;
// cerr << k << " -th in range " << lb << " " << ub << endl;
// cerr << "size: " << cn << endl;
v.reserve(cn);
v.clear();
for (ll i = 0; i < n; i++) {
ull t = next_random();
if (lb <= t && t <= ub) {
v.push_back(t);
}
}
// cerr << "real size: " << v.size() << endl;
nth_element(v.begin(), v.begin() + k, v.end());
// sort(v.begin(), v.end());
return v[k];
}
ull get_kth(ull ts0, ll n, ll k)
{
s0 = ts0;
if (n < MX_PART) {
s0 = ts0;
v.reserve(n);
v.clear();
for (int i = 0; i < n; i++)
{
v.push_back(next_random());
}
sort(v.begin(), v.end());
return v[k];
} else
{
s0 = ts0;
// cerr << k << "-th" << endl;
divide[0] = 0;
for (int i = 1; i < MX_PART; i++)
divide[i] = next_random();
memset(cnt, 0, sizeof cnt);
sort(÷[0], ÷[MX_PART]);
// for (int i = 0; i < MX_PART; i++)
// cerr << divide[i] << endl;
s0 = ts0;
//--
for (int i = 0; i < n; i++)
{
// if (i % 1000000 == 0)
// cerr << "add_to_part " << i << endl;
add_to_part(next_random());
}
// for (int i = 0; i < MX_PART; i++)
// cerr << i << "-th part: " << cnt[i] << "\t\n"[i % 5 == 0];
// cerr << "\n";
//--
for (int i = 0; i < MX_PART; i++)
if (k < cnt[i])
{
// cerr << i << "-th part with " << cnt[i] << " numbers.\n";
return get_kth_2(ts0, n, cnt[i], k, divide[i], divide[i + 1] - 1);
}
else
k -= cnt[i];
assert(0);
}
}
int main()
{
ll L, n;
cin >> A >> B >> L >> n >> s0;
cout << get_kth(s0, n, L - 1) << endl;
return 0;
}
/****
5 7 1000 400000000 13
****/