学大佬来一波题解。。。。。
A. Be Positive
题意:给你一个数组 a , a 里面的每一个数除以一个相同的数 x , 得到的新的 a 数组 , 若该数组里的正数或负数的个数大于数组长度的一半 , 便输出 x 的值 , 若没有则输出0;
思路 :记录数组里的正数和负数 , 判断他们有没有大于数组长度的一半 , 若有直接输出 1 或 -1 , 若没有输出 0 ;
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3+8;
int a[maxn];
int main()
{
int n , num1 = 0 , num2 = 0 , ans , ret , op;
cin >> n;
for(int i = 1 ; i <= n ; i++)
{
cin >> a[i];
if(a[i] > 0)
{
num1++;
}
else if(a[i] < 0)
{
num2++;
}
else
{
continue;
}
}
ans = n/2;
if(n % 2 != 0)
{
ans = n/2+1;
}
if(num1 >= ans)
{
cout << "1"<<endl;
}
else if (num2 >= ans)
{
cout <<"-1"<<endl;
}
else
{
cout <<"0" << endl;
}
return 0;
}
B. Two Cakes
题意:有俩个人 , 他们现在要各做一个N层的蛋糕 , 有2*N个房子 , 每个房子里有一层型号的蛋糕 , 蛋糕要从小到大收集。
相邻房子之间的距离为 1 , 俩个人的初始起点都在最左边的房子。问完成蛋糕后俩人走的最短步数是多少。
思路:
A , B 俩个人从最左边开始先找 1 这个房间 ,(A 去了B就要去另一个房间了) ,然后分别往下找,在所有的可能性中找到最少的那个。
将这些房间从小到大排好序(但他们的标号不变),再根据标号的加减确定步数。
例:
标号: 1 2 3 4 5 6 7 8
房间 :4 1 3 2 2 3 1 4
排序后:
标号: 2 7 4 5 3 6 1 8
房间:1 1 2 2 3 3 4 4
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+8;
struct node
{
int num;
int op;
}a[maxn];
int cmp(node a , node b)
{
return a.num < b.num;
}
int main()
{
int n ;
long long ans = 0;
cin >> n;
for(int i = 1 ; i <= 2*n ; i++)
{
cin >> a[i].num;
a[i].op = i;
}
int ret = a[1].op;
sort(a+1 , a+n*2+1 , cmp);
// printf("a[1].op = %d a[2].op = %d\n" , a[1].op , a[2].op);
ans += abs(a[1].op - ret);
ans += abs(a[2].op - ret);
// cout <<"ans = "<<ans << endl;
int x = 0 , y = 0;
for(int i = 3 ; i <= 2*n; i+=2)
{
// cout <<"a[i].op = "<<a[i].op <<endl;
x =abs(a[i].op-a[i-2].op) + abs(a[i+1].op-a[i-1].op);
y = abs(a[i].op-a[i-1].op) + abs(a[i+1].op-a[i-2].op);
// cout <<"x = "<<x<<" "<<"y = "<<y <<endl;
ans += min(x , y);
}
cout << ans << endl;
return 0;
}
C. Connect
题意:给你俩个坐标 , 分别是起始坐标和终点坐标,可以上下左右走 ,但遇海洋不能走。再给你一个地图 , 0 为陆地 , 1 为海洋。
最多只能建造一条隧道跨过海洋连接俩个陆地 , 使得可以从起点走到终点。隧道的成本是 (rs−rt)^2+(cs−ct)^2
思路:
找包含起点和终点的俩个连通块,然后暴力找最小成本 , 如果起点和终点在一个连通块中 , 就不需要成本了。
代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int vis[100][100] , Map[100][100] , ans = INF;
char arr[100][100];
int n , r1 , c1 , r2 , c2;
int dis[4][2] = {0 , 1 , 1 , 0 , 0 , -1 , -1 ,0};
struct node
{
int x;
int y;
node(int x , int y):x(x) , y(y){}
};
int check(int x , int y)
{
if(x < 0 || y < 0 || x >= n || y >= n || vis[x][y] == 1 || arr[x][y] == '1')
return 0;
return 1;
}
int answer(int x1 , int y1 , int x2 , int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
void bfs(int x , int y , int k)
{
queue<node> Q;
vis[x][y] = 1;
Q.push(node(x , y));
while(!Q.empty())
{
node p = Q.front();
Q.pop();
Map[p.x][p.y] = k;
for(int i = 0 ; i < 4 ; i++)
{
int xx = p.x + dis[i][0];
int yy = p.y + dis[i][1];
if(check(xx , yy))
{
vis[xx][yy] = 1;
Q.push(node(xx , yy));
}
}
}
}
int main()
{
int sum = 0;
cin >> n >> r1 >> c1 >> r2 >> c2;
r1--,r2--,c2--,c1--;
for(int i = 0 ; i < n ; i++)
{
cin >>arr[i];
}
for(int i = 0 ; i < n ; i++)
{
for(int j = 0 ; j < n ; j++)
{
if(vis[i][j] == 0 && arr[i][j] == '0')
{
bfs(i , j , sum++);
}
}
}
if(Map[r1][c1] == Map[r2][c2])
{
cout <<"0"<<endl;
}
else
{
for(int i = 0 ; i < n ; i++)
{
for(int j = 0 ; j < n ; j++)
{
if(arr[i][j] == '0' && Map[i][j] == Map[r1][c1])
{
for(int w = 0 ; w < n ; w++)
{
for(int s = 0 ; s < n ; s++)
{
if(arr[w][s] == '0' && Map[w][s] == Map[r2][c2])
{
ans = min(ans , answer(i , j , w , s));
}
}
}
}
}
}
cout << ans;
}
return 0;
}
D2. Toy Train
题意:有形成圆的N个站点 , 每个站点有0或多个糖果 , 糖果标记了自己要去的目的站。火车从起点循环顺时针开,每经过一个站点都可以带上一个糖果 , 到达目标站可放下该糖果 , 注意 , 在一个站只能带上一个糖果,火车的容量无限大。
俩站点之间火车花费 1 秒 , 搬运糖果的时间不计。求以每个站点为起点时花费的最少时间是多少;
思路:
i 表示起点 , j 表示糖果数最多的站点 , k 表示该站点最后一个糖果的目标站点。
num为糖果数 , dis[i][j] 表示 i 到 j 的步数
那么就有 ans = (num-1)* n + dis[i][j] + dis[j][k];
循环每个起点 , 以及该起点下循环每个站点 , 以及该站点下每个糖果的目标地,求最小值。
代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
vector<int>V[5080];
int main()
{
int n , m, a , b , ans , op;
cin >> n >> m;
for(int i = 0 ; i < m ; i++)
{
cin >> a >> b;
V[a].push_back(b);
}
for(int i = 1 ; i <= n ; i++)
{
ans = 0;
for(int j = 1 ; j <= n ; j++)
{
op = INF;
int num = V[j].size();
if(num == 0)continue;
for(auto k : V[j])
{
op = min(op , (num-1)*n+(j-i+n) %n+(k-j+n)%n);
}
ans = max(ans , op);
}
cout <<ans <<" ";
}
return 0;
}