2022ZJCPC部分题目

2022ZJCPC 部分题目

G

题目链接:2022ZJCPC G

要求从一点到另一点的最短时间,可转化为求一点到另一点的最短路。

只需要预处理一点到另一点的距离,分为从原点与终点出发的和从其他点出发的即可,其他点出发的会有三秒的加速。

最后求一个最短路即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ld long double
using namespace std;
struct node{
double x,y;
};
struct dis{
int u;
double w;
};
double v1,v2;
const int MAXN=1e3+5;
node point[MAXN];
int vis[MAXN];
double dis1[MAXN];
vector<dis>arr[MAXN];
double distance(struct node x,struct node y){
double ans=pow((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y),0.5);
return ans;
}
int n;
void dijkstra(int n, int s) {
fill(dis1,dis1+MAXN,10000000000);
dis1[s] = 0;
for (int i = 1; i <= n; i++) {
int u = 0, mind = 1e9;
for (int j = 1; j <= n; j++){
if (!vis[j] && dis1[j] < mind) u = j, mind = dis1[j];
}
vis[u] = true;
for (auto ed : arr[u]) {
int v = ed.u;
double w = ed.w;
if (dis1[v] > dis1[u] + w) dis1[v] = dis1[u] + w;
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n+2;i++){
cin>>point[i].x>>point[i].y;
}
cin>>v1>>v2;
dis index;
for(int i=n+1;i<=n+2;i++){
for(int j=1;j<=n+2;j++){
index.u=j;
index.w=distance(point[i],point[j])/v1;
arr[i].push_back(index);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n+2;j++){
index.u=j;
if(distance(point[i],point[j])/v2<=3){
index.w=distance(point[i],point[j])/v2;
}
else {
index.w=3+(distance(point[i],point[j])-3*v2)/v1;
}
arr[i].push_back(index);
}
}
dijkstra(n+2,n+1);
printf("%lf",dis1[n+2]);
}

L

题目链接:2022ZJCPC J

假设最后集合的平均数为k,则无脑选择小于等于k的数,对大于k的数从小开始取。

故对数sort后,所选择的序列必定是一个前缀。

可先确定前缀,最后用upper_bound确定大于平均数的数量。

由于是1e6数量的1e9大小的输入,需要读入优化。(因为没优化T过)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ld long double
using namespace std;
int n;
int arr[1000005];
ll pre[1000005];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>arr[i];
}
sort(arr+1,arr+1+n);
for(int i=1;i<=n;i++){
pre[i]=pre[i-1]+arr[i];
}
int maxn=0;
for(int i=1;i<=n;i++){
ll index=pre[i]/i;
int sum=upper_bound(arr+1,arr+i,index)-arr-1;
sum=i-sum;
maxn=max(sum,maxn);
}
cout<<maxn;
}

M

题目链接:2022ZJCPC M

设中心图像(黑格包裹的白格)为x,可以统计黑白格的数量,进行解方程,解得两种图形的数量。

注意在query的时候要检测6x6的方格,而不是4x4。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ld long double
using namespace std;
int a,b;
char arr[1005][1005];
char vis[][7]=
{
"######",
"##..##",
"#....#",
"#....#",
"##..##",
"######"
};

bool query(int i,int j){
if(i+5>a||j+5>b){
return 0;
}
for(int p=0;p<=5;p++){
for(int q=0;q<=5;q++){
if(arr[i+p][j+q]!=vis[p][q])return 0;
}
}
return 1;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>a>>b;
int black=0;
int white=0;
int hole=0;
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++){
cin>>arr[i][j];
if(arr[i][j]=='#')black++;
else white++;
}
}
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++){
if(query(i,j))hole++;
}
}
int x=(100*hole-black)/54;
int y=hole-2*x;
cout<<x<<' '<<y;
return 0;
}

其实有更简单暴力的方法就是每次query成功后直接对(i+7 , j) (i-7 , j) (i , j-7) (i , j+7)进行query,

如果有一个成立那么x++,如果没有,那么y++。

由于x算了两次,最后x需要除2。

最后直接输出x与y。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ld long double
using namespace std;
int a,b;
char arr[1005][1005];
char vis[][7]=
{
"######",
"##..##",
"#....#",
"#....#",
"##..##",
"######"
};

bool query(int i,int j){
if(i+5>a||j+5>b){
return 0;
}
for(int p=0;p<=5;p++){
for(int q=0;q<=5;q++){
if(arr[i+p][j+q]!=vis[p][q])return 0;
}
}
return 1;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>a>>b;
int x=0;
int y=0;
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++){
cin>>arr[i][j];
}
}
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++){
if(query(i,j)){
if(i+7<=a&&query(i+7,j))x++;
else if(i-7>=1&&query(i-7,j))x++;
else if(j-7>=1&&query(i,j-7))x++;
else if(j+7<=b&&query(i,j+7))x++;
else y++;
}
}
}
cout<<x/2<<' '<<y;
return 0;
}

2022ZJCPC部分题目
https://shepherdzzx.github.io/2022ZJCPC部分题目/
Author
Shepherdz
Posted on
May 16, 2024
Licensed under