📜  门| GATE CS 2018 |第 51 题(1)

📅  最后修改于: 2023-12-03 14:58:20.040000             🧑  作者: Mango

门| GATE CS 2018 |第 51 题

这是一道来自于 GATE CS 2018 的编程题目,要求使用 C 语言实现一个程序。

题目描述

给定一个无向图,每个节点有一个 0 或 1 的权重值,以及一个门,门可能会打开或关闭。

门最初是关闭的。其中每个节点都应该有一个“和”值,这个值定义为该节点到其他节点之间连接路径上的点的权重和(包括自己)。

你的任务是编写一个算法来决定门是否应该打开。门将打开当且仅当所有节点的和值都是偶数。

你需要实现以下两个函数:

void setValue(int i, int v);
int query();
  • setValue(i, v):设置节点i的权重值为v(0或1),0 ≤ i < n,其中n为节点的个数。
  • query:返回门是否应该打开。如果门应该打开则返回1,否则返回0。

假设该图是连通的。

输入说明

输入的第一行是一个整数n,表示节点的个数。接下来的n行,每行包括两个整数,用来描述节点的权重值和。

输出说明

输出门的状态,如果门应该打开则输出1,否则输出0。

样例

输入:

5
0 1
0 0
1 0
1 0
1 1

输出:

1
题目分析

首先我们需要理解问题所述的“和”值含义,它们是节点到其他节点之间连接路径上的点的权重和(包括自己)。

因此,我们可以遍历每个节点,并计算从当前节点出发到其他节点的路径上的权重和,将该值存储到相应的节点“和”值中。

在setValue函数中,我们需要更新节点i的权重值为v(0或1)。因此,我们将节点i的权重值更新为v,并更新从该节点出发到其他节点的路径上的权重和。

在query函数中,我们遍历每个节点,并检查它们的“和”值是否为偶数。当节点“和”值无法被2整除时,我们可以停止遍历并将门状态设置为关闭,返回0。否则,当所有节点的“和”值都是偶数时,我们将门状态设置为打开,返回1。

代码实现

下面是使用C语言实现了该算法的代码片段,注意返回的是markdown格式:

```c
#include <stdio.h>

#define MAX_NODES 100

int n, door = 0;
int weights[MAX_NODES];
int cum_sum[MAX_NODES]; 

void setValue(int i, int v){
    int delta = v - weights[i];
    weights[i] = v;
    for (int j = 0; j < n; j++){
        if(j == i) continue;
        if(cum_sum[j] % 2 == 0){ 
            cum_sum[j] += delta;
        }else{
            if((cum_sum[j] + delta) % 2 == 0){
                door = 1;
            }else{
                door = 0;
                break;
            }
            cum_sum[j] += delta;
        }
    }
}

int query(){
    return door;
}

int main(){
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        int val, wt = 0;
        scanf("%d %d", &val, &wt);
        weights[i] = val;
        cum_sum[i] = val;
    }

    for(int i = 0; i < n; i++){
        for(int j = i + 1; j < n; j++){
            if (i != j) cum_sum[i] += (weights[i] + weights[j]);
        }
    }

    if(query() == 1){
        printf("门应该打开");
    }else{
        printf("门应该关闭");
    }
    return 0;
}

注意:为了方便,上述代码省略了输入输出处理。请按照题目描述自行实现。