用c语言实现:小明得知在沁湖边上有n个点,这几个点从1到n顺时针为国成一圈,每个点栽有一颗花树。有四种花树:梅花(花期1-3月系、樱花(花期3-4月)、石楠花(花期4-5月)、桂花(花期9-10月),每种花只在自己的花期开花。小明给每个点标记一个值p,p;的值表示该点是哪种花公 1代表梅花,2代表樱花,了代表石楠花,4代表桂花。小明现在制定了m种观赏方案,每次选定一个月份z,在江月去赏花,在由于沁湖太大,小明就选了湖边两个点u和v ,想着就欣赏从u到v沿途的花就好了,因为湖中有桥,现在他发现从u走到v有了几种不同的方式,他想知道沿途最多能看到多少棵树正在开花(走到一个点才能看见这个点的花是否开了,不能重复经过同一个点)。 要求: (1) 如地点用结构体类型(至少包括种什么类型的花、是否能看到花) struct place {int f type;//1-4 int if open;//0没开,开放 }; 提示:利用malloc 建立动态数组 出发点和结束点考虑在桥的同侧还是异侧。
时间: 2024-02-20 09:56:45 浏览: 66
以下是实现该问题的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
struct place {
int flower_type; // 1-4,分别表示梅花、樱花、石楠花、桂花
int is_open; // 0表示没开,1表示开放
};
int max(int a, int b) {
return a > b ? a : b;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
struct place *places = (struct place*) malloc(n * sizeof(struct place));
for (int i = 0; i < n; i++) {
scanf("%d", &(places[i].flower_type));
places[i].is_open = 0; // 初始时都没开放
}
int z, u, v;
while (m--) {
scanf("%d %d %d", &z, &u, &v);
u--; v--; // 转为0-based indexing
int ans = 0;
for (int i = 0; i < n; i++) {
places[i].is_open = (z >= (places[i].flower_type - 1) * 3 + 1 && z <= places[i].flower_type * 3); // 判断该点是否开放
}
if (u == v) { // 起点和终点相同
ans = places[u].is_open;
} else {
int p1 = u, p2 = u + 1; // p1和p2是u和v的下一个点
int dir = 1; // dir表示当前方向,1表示顺时针,-1表示逆时针
int cnt1 = places[u].is_open, cnt2 = 0; // cnt1和cnt2分别表示p1和p2的花树数
while (p1 != v && p2 != v) {
if (dir == 1) {
cnt2 += places[p2].is_open;
if (cnt2 > cnt1) {
cnt1 = cnt2;
cnt2 = 0;
p1 = p2;
p2 = (p1 + 1) % n;
} else {
p2 = (p2 + 1) % n;
}
} else {
cnt1 += places[p1].is_open;
if (cnt1 > cnt2) {
cnt2 = cnt1;
cnt1 = 0;
p2 = p1;
p1 = (p2 + n - 1) % n;
} else {
p1 = (p1 + n - 1) % n;
}
}
dir = -dir;
}
ans = max(cnt1, cnt2);
}
printf("%d\n", ans);
}
free(places);
return 0;
}
```
首先读入n和m,然后利用malloc动态分配一个大小为n的数组places,存放每个点的信息。接着对于每个方案,读入月份z和起点u以及终点v,然后遍历所有点,计算出该点是否开放。接着根据起点和终点的关系,计算出沿途最多能看到多少棵树正在开花。
具体地,如果起点和终点相同,直接返回该点的花树数。否则,我们从起点出发,维护两个指针p1和p2,它们分别指向起点的下一个点和下下个点(即p2 = (p1 + 1) % n)。我们同时维护一个方向dir,它表示当前是顺时针方向还是逆时针方向。一开始dir设为1,表示顺时针。我们还维护两个计数器cnt1和cnt2,分别表示p1和p2沿途能看到的花树数。
然后我们开始移动p1和p2。如果dir为1,我们先判断p2是否开放,如果开放就将cnt2加上它能看到的花树数。然后我们判断cnt2是否大于cnt1,如果大于,就将cnt1更新为cnt2,cnt2清零,p1更新为p2,p2更新为p1的下一个点。如果cnt2不大于cnt1,就将p2更新为p2的下一个点。如果dir为-1,我们同样先判断p1是否开放,如果开放就将cnt1加上它能看到的花树数。然后我们判断cnt1是否大于cnt2,如果大于,就将cnt2更新为cnt1,cnt1清零,p2更新为p1,p1更新为p2的下一个点。如果cnt1不大于cnt2,就将p1更新为p1的下一个点。每次移动后,我们还要将方向dir取反。
当p1或p2等于终点v时,我们停止移动,此时沿途最多能看到的花树数就是cnt1和cnt2中的较大值。
最后别忘了在程序结束前释放动态分配的数组places。
阅读全文