第46屆ICPC 東亞洲區域賽(澳門)(熱身賽)
A. K-skip Permutation
链接:https://ac.nowcoder.com/acm/contest/31453/A
来源:牛客网
题目描述
For a permutation P=p1,p2,⋯ ,pnP=p1,p2,⋯,pn of nn, let f(P,k)f(P,k) be the number of ii satisfying 1≤i<n1≤i<n and pi+k=pi+1pi+k=pi+1.
Given two integers nn and kk, your task is to find a permutation PP of nn such that f(P,k)f(P,k) is maximized.
Recall that in a permutation of nn, each integer from 11 to nn (both inclusive) appears exactly once.
输入描述:
There is only one test case in each test file.
The first and only line contains two integers nn and kk (1≤n,k≤1061≤n,k≤106).
输出描述:
Output one line containing nn integers indicating a permutation PP of nn that maximizes f(P,k)f(P,k). If there are multiple valid answers you can output any of them.
Please, DO NOT output extra spaces at the end of the line, or your answer may be considered incorrect!
示例1
输入
复制
3 1
输出
复制
1 2 3
示例2
输入
复制
7 3
输出
复制
2 5 1 4 7 3 6
示例3
输入
复制
3 7
输出
复制
1 3 2
找出模k=0的所有数,模k=1的所有数...分别从小到大输出即可。因为属于不同组的两个数对答案显然没有贡献。证明如下:设\(x=pk+a,y=qk+b\),且\(x<y\),则\(y-x=(b-a)+(q-p)k\)。因为\(b-a\neq0\)(两个数属于不同组),因此做差后不可能等于\(k\)。
#include <bits/stdc++.h>
using namespace std;
bool v[2000005];
vector<int> ans[1000005];
int main() {
int n, k;
cin >> n >> k;
for(int i = 1; i <= n; i++) {
ans[i % k].push_back(i);
}
for(int i = 0; i < k; i++) {
for(auto x : ans[i]) cout << x << " ";
}
return 0;
}
B. Hotpot
链接:https://ac.nowcoder.com/acm/contest/31453/B
来源:牛客网
题目描述
Sichuan hotpot is one of the most famous dishes around the world. People love its spicy taste.
There are nn tourists, numbered from 00 to (n−1)(n−1), sitting around a hotpot. There are kk types of ingredients for the hotpot in total and the ii-th tourist favors ingredient aiai most. Initially, every tourist has a happiness value of 00and the pot is empty.
The tourists will perform mm moves one after another, where the ii-th (numbered from 00 to (m−1)(m−1)) move is performed by tourist (imod n)(imodn). When tourist tt moves:
- If ingredient atat exists in the pot, he will eat them all and gain 11 happiness value.
- Otherwise, he will put one unit of ingredient atat into the pot. His happiness value remains unchanged.
Your task is to calculate the happiness value for each tourist after mm moves.
输入描述:
There are multiple test cases. The first line of the input contains an integer TT (1≤T≤1031≤T≤103) indicating the number of test cases. For each test case:
The first line contains three integers nn, kk and mm (1≤n≤1051≤n≤105, 1≤k≤1051≤k≤105, 1≤m≤1091≤m≤109) indicating the number of tourists, the number of types of ingredients and the number of moves.
The second line contains nn integers a0,a1,⋯ ,an−1a0,a1,⋯,an−1 (1≤ai≤k1≤ai≤k) where aiai indicates the favorite ingredient of tourist ii.
It's guaranteed that neither the sum of nn nor the sum of kk of all the test cases will exceed 2×1052×105.
输出描述:
For each test case output nn integers h0,h1,⋯ ,hn−1h0,h1,⋯,hn−1 in one line separated by a space, where hihi indicates the happiness value of tourist ii after mm moves.
Please, DO NOT output extra spaces at the end of each line, or your answer might be considered incorrect!
示例1
输入
复制
4
3 2 6
1 1 2
1 1 5
1
2 2 10
1 2
2 2 10
1 1
输出
复制
0 2 1
2
2 2
0 5
首先可以知道每类对应的数量不是0就是1,且经过偶数轮后所有类的数量都会变成0。因此可以求出经过前两轮后每类材料的答案。设总轮数为round = m / n,剩余的操作次数为res = m % n,如果m < n的话直接暴力跑;如果round为奇数且不为1(为1的话直接暴力跑),则先跑两轮求出贡献,然后把每类材料的答案乘以round / 2,剩下一轮和res暴力跑;如果round为偶数直接跑两轮然后把每类材料的答案乘以round / 2,res暴力跑。代码写的比较丑~
#include <bits/stdc++.h>
using namespace std;
int n, m, k;
int a[100004], b[100005], tans[100005];
int main() {
int t;
cin >> t;
while(t--) {
cin >> n >> k >> m;
for(int i = 0; i < n; i++) {
cin >> a[i];
tans[i] = 0;
}
for(int i = 0; i <= k; i++) b[i] = 0;
int round = m / n, res = m % n;
if(round) {
for(int i = 0; i < n; i++) {
if(b[a[i]]) {
tans[i]++; b[a[i]]--;
} else {
b[a[i]]++;
}
}
if(round & 1) {
if(round > 1) {
for(int i = 0; i < n; i++) {
if(b[a[i]]) {
tans[i]++; b[a[i]]--;
} else {
b[a[i]]++;
}
}
for(int i = 0; i < n; i++) tans[i] *= (round / 2);
for(int i = 0; i < n; i++) {
if(b[a[i]]) {
tans[i]++; b[a[i]]--;
} else {
b[a[i]]++;
}
}
}
} else {
for(int i = 0; i < n; i++) {
if(b[a[i]]) {
tans[i]++; b[a[i]]--;
} else {
b[a[i]]++;
}
}
for(int i = 0; i < n; i++) tans[i] *= (round / 2);
}
for(int i = 0; i < res; i++) {
if(b[a[i]]) {
tans[i]++; b[a[i]]--;
} else {
b[a[i]]++;
}
}
for(int i = 0; i < n; i++) cout << tans[i] << " ";
cout << endl;
} else {
for(int i = 0; i < m; i++) {
if(b[a[i]]) {
tans[i]++; b[a[i]]--;
} else {
b[a[i]]++;
}
}
for(int i = 0; i < n; i++) cout << tans[i] << " ";
cout << endl;
}
}
}
C. Wandering Robot
链接:https://ac.nowcoder.com/acm/contest/31453/C
来源:牛客网
题目描述
DreamGrid creates a programmable robot to explore an infinite two-dimension plane. The robot has a basic instruction sequence a1,a2,…ana1,a2,…an and a "repeating parameter" kk, which together form the full instruction sequence s1,s2,…,sn,sn+1,…,snks1,s2,…,sn,sn+1,…,snk and control the robot.
There are 4 types of valid instructions in total, which are U' (up),
D' (down), L' (left) and
R' (right). Assuming that the robot is currently at (x,y)(x,y), the instructions control the robot in the way below:
- U: Moves the robot to (x,y+1)(x,y+1).
- D: Moves the robot to (x,y−1)(x,y−1).
- L: Moves the robot to (x−1,y)(x−1,y).
- R: Moves the robot to (x+1,y)(x+1,y).
The full instruction sequence can be derived from the following equations
{si=aiif 1≤i≤nsi=si−notherwise{si=aisi=si−nif 1≤i≤notherwise
The robot is initially at (0,0)(0,0) and executes the instructions in the full instruction sequence one by one. To estimate the exploration procedure, DreamGrid would like to calculate the largest Manhattan distance between the robot and the start point (0,0)(0,0) during the execution of the nknk instructions.
Recall that the Manhattan distance between (x1,y1)(x1,y1) and (x2,y2)(x2,y2) is defined as ∣x1−x2∣+∣y1−y2∣∣x1−x2∣+∣y1−y2∣.
输入描述:
There are multiple test cases. The first line of the input contains an integer TT indicating the number of test cases. For each test case:
The first line contains two integers nn and kk (1≤n≤105,1≤k≤1091≤n≤105,1≤k≤109), indicating the length of the basic instruction sequence and the repeating parameter.
The second line contains a string A=a1a2…anA=a1a2…an (∣A∣=n∣A∣=n, ai∈{’L’,’R’,’U’,’D’}ai∈{’L’,’R’,’U’,’D’}), where aiai indicates the ii-th instruction in the basic instriction sequence.
It's guaranteed that the sum of ∣A∣∣A∣ of all test cases will not exceed 2×1062×106.
输出描述:
For each test case output one line containing one integer indicating the answer.
示例1
输入
复制
2
3 3
RUL
1 1000000000
D
输出
复制
4
1000000000
备注:
For the first sample test case, the final instruction sequence is "RULRULRUL" and the route of the robot is (0, 0) - (1, 0) - (1, 1) - (0, 1) - (1, 1) - (1, 2) - (0, 2) - (1, 2) - (1, 3) - (0, 3). It's obvious that the farthest point on the route is (1, 3) and the answer is 4.
忘了是哪场比赛的原题了,可以发现对于字符串的每一个操作所处的位置一定在一条直线上,因此对于每个位置求出直线的两个端点计算对答案的贡献即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int tx[1000005], ty[1000005];
signed main() {
int t;
cin >> t;
while(t--) {
int n, k;
cin >> n >> k;
string s;
cin >> s;
int x = 0, y = 0;
int ex, ey;
for(int i = 0; i < n; i++) {
if(s[i] == 'U') y++;
else if(s[i] == 'D') y--;
else if(s[i] == 'L') x--;
else x++;
tx[i] = x, ty[i] = y;
}
ex = x, ey = y;
int ans = 0;
for(int i = 0; i < n; i++) {
ans = max(ans, abs(tx[i]) + abs(ty[i]));
ans = max(ans, abs(tx[i] + (k - 1) * ex) + abs(ty[i] + (k - 1) * ey));
}
cout << ans << endl;
}
return 0;
}