Codeforces Round #542 (Div. 2) 题解
A. Be Positive
-
题意
给定一个整数序列 a a a,现在需要你构造出一个非零整数 d d d,使得所有的 a i a_i ai变成 a i / d a_i/d ai/d,操作完之后序列中出现的正数数量要 ≥ ⌈ n 2 ⌉ \geq \lceil\frac{n}{2}\rceil ≥⌈2n⌉。如果不存在这样的 d d d,输出 0 0 0。 -
解题思路
实际上不管我们怎么选取 d d d,我们改变的也是序列中数的正负性, 0 0 0还是 0 0 0。所以我们只需要统计出正数和负数的个数,然后判断哪个满足即可。如果都不符合,那么 d d d就不存在。 -
AC代码
/**
*@filename:A
*@author: pursuit
*@created: 2021-09-10 15:40
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n, a[N], cnt0, cnt1;
void solve(){
if(cnt0 >= (n + 1) / 2){
cout << 1 << endl;
}
else if(cnt1 >= (n + 1) / 2){
cout << -1 << endl;
}
else{
cout << 0 << endl;
}
}
int main(){
cin >> n;
for(int i = 1; i <= n; ++ i){
cin >> a[i];
if(a[i] > 0)++ cnt0;
else if(a[i] < 0)++ cnt1;
}
solve();
return 0;
}
B. Two Cakes
-
题意
两个人买蛋糕,蛋糕一层比一层小,规定先买小,再买大,即先买1,再买2,…最后买n。有 2 n 2n 2n家店,每家店都是只出售一个等级蛋糕的一个,相邻蛋糕店的距离为1,两人刚开始都在最左边,问两个人最少走多长距离可以买好两个蛋糕。 -
解题思路
我们知道,一共右两个店售卖第 i i i层的蛋糕,那么第一个人按顺序购买去最靠左的蛋糕店购买即可,同理,第二个则按顺序购买去最靠右的蛋糕店购买即可。计算二者代价之和。根据贪心原则,此不会作多余的无用功,此题得解。 -
AC代码
/**
*@filename:B
*@author: pursuit
*@created: 2021-09-10 15:43
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
//每家糕点店只能购买一个特定尺寸的层。即在第i家能购买到ai的层。
int n;
vector<int> a[N];
void solve(){
ll cnt = 0, pre = 1;
for(int i = 1; i <= n; ++ i){
int cur = a[i][0];
cnt += abs(cur - pre);
pre = cur;
}
pre = 1;
for(int i = 1; i <= n; ++ i){
int cur = a[i][1];
cnt += abs(cur - pre);
pre = cur;
}
printf("%lld\n", cnt);
}
int main(){
scanf("%d", &n);
for(int i = 1, x; i <= 2 * n; ++ i){
scanf("%d", &x);
a[x].push_back(i);
}
solve();
return 0;
}
C. Connect
-
题意
给你一个网格地图,其中位置 ( i , j ) (i,j) (i,j)处如果 s [ i ] [ j ] s[i][j] s[i][j]为0
代表陆地,否则为海洋。现在你从起点出发,只能陆地上行走,当然你可以建立一个传送门从一个陆地点 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)到另一个陆地点 ( x 2 , y 2 ) (x_2,y_2) (x2,y2),代价为 ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 (x_2-x_1)^2+(y_2-y_1)^2 (x2−x1)2+(y2−y1)2。问你到达终点所需的最小代价。 -
解题思路
将起点和终点所处的连通块的所有点存储起来,再暴力枚举两个连通块点建立传送门的代价取最小即可。 -
AC代码
/**
*@filename:C
*@author: pursuit
*@created: 2021-09-10 15:57
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 50 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
//创建最多一条隧道的最低成本。以便可以从(r1, c1)到达(r2, c2)。
int n;
char s[N][N];//如果为陆地则为0,否则为1。
int go[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}, minn;
bool vis[N][N];
pii st, ed;
queue<pii> q;
int distance(pii st, pii ed){
return (st.x - ed.x) * (st.x - ed.x) + (st.y - ed.y) * (st.y - ed.y);
}
void bfs(pii x, vector<pii> &a){
pii u, v;
q.push(x);
while(!q.empty()){
u = q.front();
a.push_back(u);
q.pop();
vis[u.x][u.y] = true;
for(int i = 0; i < 4; ++ i){
v.x = u.x + go[i][0], v.y = u.y + go[i][1];
if(v.x >= 1 && v.x <= n && v.y >= 1 && v.y <= n && s[v.x][v.y] == '0' && !vis[v.x][v.y]){
q.push(v);
}
}
}
}
void solve(){
//枚举所建隧道。
//直接bfs。碰到不行的就退出。每到一个点取min。
minn = INF;
vector<pii> a, b;
bfs(st, a), bfs(ed, b);
for(auto u : a){
//cout << u.x << " " << u.y << endl;
for(auto v : b){
minn = min(minn, distance(u, v));
}
}
cout << minn << endl;
}
int main(){
cin >> n;
cin >> st.x >> st.y >> ed.x >> ed.y;
for(int i = 1; i <= n; ++ i){
cin >> s[i] + 1;
}
solve();
return 0;
}
D1.D2. Toy Train
-
题意
一个环形铁路,有一趟火车,这个火车每一次只能从每一个车站运送一颗糖果。每一个车站有多个糖果,并且这些糖果都有其目标车站。问从每一个车站出发,运送完所有糖果所要时间是多少。 -
解题思路
对于每个站点 i i i,假设这个站点的糖果种类为 x x x,那么运送完这个车站的糖果一定要走 x − 1 x-1 x−1圈,由于走了 ( x − 1 ) 圈 (x- 1)圈 (x−1)圈,那么还剩下最后一个糖果没有运送。所以影响最后的结果的就是最后一次运送的糖果,则我们的时间消耗为: S i = d i s t ( s t , i ) + n ( x − 1 ) + d i s t ( a i , b i ) S_i=dist(st,i)+n(x-1)+dist(a_i,b_i) Si=dist(st,i)+n(x−1)+dist(ai,bi)。然后对于其他的站点的糖果也是这个代价,我们取最大值即可。 -
AC代码
/**
*@filename:D1
*@author: pursuit
*@created: 2021-09-10 16:41
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
//糖果i现在在站ai,需要送到站bi。找到运送所有糖果的最短时间。
int n, m;//站数和糖果数量。
//火车一次占用一个车站。一次只能带走一种类型的物品。
vector<int> st[N];
int res;
void solve(){
for(int i = 1; i <= n; ++ i){
sort(st[i].begin(), st[i].end());
}
for(int i = 1; i <= n; ++ i){
int res = 0, cost = 0;
for(int j = 1; j <= n; ++ j){
//起始站在i站。
if(st[j].size() == 0)continue;
if(i <= j){
cost = j - i;
}
else{
cost = n - (i - j);
}
int k = st[j].size() - 1;
cost += k * n + st[j][0];
res = max(res, cost);
}
cout << res << " ";
}
cout << endl;
}
int main(){
cin >> n >> m;
for(int i = 1, u, w; i <= m; ++ i){
cin >> u >> w;
if(u <= w){
w -= u;
}
else{
w = n - (u - w);
}
st[u].push_back(w);
}
solve();
return 0;
}
E. Wrong Answer
-
给出一段程序错误程序计算 max 0 ≤ l ≤ r ≤ n − 1 ∑ l ≤ i ≤ r ( r − l + 1 ) ⋅ a i \max\limits_{0 \leq l \leq r \leq n-1} \sum\limits_{l \leq i \leq r} (r-l+1) \cdot a_i 0≤l≤r≤n−1maxl≤i≤r∑(r−l+1)⋅ai。现在需要你构造出一个序列使得通过错误程序计算出的答案和正确的最大值相差正好为 k k k。
-
解题思路
我们固定 a 0 = − 1 a_0=-1 a0=−1,那么根据错误程序 a 0 a_0 a0是选不了的,所以我们可以假定后面的元素全部为非负数,那么正确的答案为 n s ns ns,错误的答案为 ( n − 1 ) ⋅ ( s + 1 ) (n-1)\cdot(s+1) (n−1)⋅(s+1),则相差 k = s − n + 1 k=s-n+1 k=s−n+1。我们可以固定 n n n来构造 a i a_i ai,需要注意的是 k k k高达 1 e 9 1e9 1e9,而 a i a_i ai最大只能取 1 e 6 1e6 1e6,所以我们 n n n取上限为 2000 2000 2000,那么依此构造 a a a序列即可。 -
AC代码
/**
*@filename:E
*@author: pursuit
*@created: 2021-09-11 10:30
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
//a1 = -1, 则n * s - (n - 1) * (s + 1) = s - n + 1 = k
int k, n = 2000;
void solve(){
cout << n << endl;
int s = k + n;
cout << -1 << " ";
int i, x = 1e6;
for(i = 2; i <= n; ++ i){
if(s > x){
cout << x << " ";
s -= x;
}
else{
cout << s << " ";
++ i;
break;
}
}
while(i ++ <= n){
cout << 0 << " ";
}
cout << endl;
}
int main(){
cin >> k;
solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!