列表

详情


NC207577. SumoandElectricity(Easy)

描述

注意:Easy与Hard版本的不同之处在于w_i的条件限制,Easy中有且仅有一个 w_i 满足

Sumo有n个核电站,每个核电站都有自己的耗电量。这些核电站之间通过m条电缆相连,电缆的传输功耗为两个核电站耗电量之间的异或(XOR)值。

但是核电站功率十分不稳定,因此Sumo并不知道部分核电站目前的功耗是怎样的,但是它可以选择调整这些核电站功耗的大小。

因为电缆的功耗远大于核电站的功耗,因此Sumo希望可以优先保证在所有电缆功耗总和尽可能低的条件下,尽量降低所有核电站的功耗总和,希望你能帮助Sumo为功耗未知的核电站设置功耗,从而满足以上的条件。

输入描述

第一行输入整数  代表有n个核电站,m条电缆。

接下来的一行中给出n个整数代表第i个核电站的功耗, 代表这个核电站的功耗未知,本题中有且仅有一个w_i满足

接下来 m 行,每行输入两个数 表示该条电缆所连接的两个核电站的编号,数据保证两个核电站之间不会有多条电缆连接。

输出描述

第一行输出一个整数表示电缆功耗总和。

第二行输出一个整数表示在电缆功耗总和尽可能低的情况下,核电站的功耗总和。

示例1

输入:

3 2
2 -1 0
1 2
2 3

输出:

2
2

原站题解

import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
Scanner scanner = new Scanner(System.in);
// todo
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Go(1.9.1) 解法, 执行用时: 25ms, 内存消耗: 3052K, 提交时间: 2020-06-06 16:00:07

package main
import (
"fmt"
)
func main() {
var m,n,a,b,cnt,all int
fmt.Scan(&n,&m)
var tt=make([]int,32)
tt[0]=1
for i:=1;i<32;i++{
tt[i]=tt[i-1]*2
}
var p=make([][]int,n+1)
var aa=make([]int,n+1)
for i:=0;i<=n;i++{
p[i]=make([]int,n+1)
}
for i:=1;i<=n;i++{
fmt.Scan(&aa[i])
if aa[i]==-1{
cnt=i
}
}
for i:=0;i<m;i++{
fmt.Scan(&a,&b)
p[a][b]=1
p[b][a]=1
}
var tmp=make([]int,32)
for i:=1;i<=n;i++{
if p[cnt][i]==0{
continue
}
all++
var t,index=aa[i],0
for t!=0{
if t&1==1{
tmp[index]++
}
index++
t>>=1
}
}
var res int
for i:=0;i<32;i++{
if tmp[i]*2>all{
res+=tt[i]
}
}
aa[cnt]=res
var dian int
for i:=1;i<=n;i++{
for j:=1;j<i;j++{
if p[i][j]!=0{
dian+=aa[i]^aa[j]
}
}
}
fmt.Println(dian)
res=0
for i:=1;i<=n;i++{
res+=aa[i]
}
fmt.Println(res)
}

Python3(3.5.2) 解法, 执行用时: 36ms, 内存消耗: 3548K, 提交时间: 2020-06-06 15:56:09

n, m = map(int, input().split())
cin = input()
a = []
b = []
ans1 = ans2 = 0
for i in cin.split():
a.append(int(i))
ans2 += int(i)
for i in range(m):
u, v = map(int, input().split())
u -= 1
v -= 1
if a[u] == -1:
b.append(a[v])
elif a[v] == -1:
b.append(a[u])
else:
ans1 += a[u] ^ a[v]
if len(b) == 0:
ans2 += 1
print(ans1)
print(ans2)
else:
cnt = []
for i in range(32):
cnt.append(0)
n = len(b)
for x in b:
p = 0
while x > 0:
if x & 1 == 1:
cnt[p] += 1
x >>= 1
p += 1
res = 0
for i in range(32):
if cnt[i] > n / 2:
res += 2 ** i
for x in b:
ans1 += res ^ x
ans2 += res + 1
print(ans1)
print(ans2)

C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 488K, 提交时间: 2020-06-17 14:06:36

#include<bits/stdc++.h>
using namespace std;
int main()
{
int i,j=0,x,y,n,m,W[505];
long long ans1=1,ans2=0,bit[35]={0};
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d",&W[i]),ans1+=W[i];
while(m--)
{
scanf("%d%d",&x,&y);
if(W[y]==-1)swap(x,y);
if(W[x]!=-1)ans2+=W[x]^W[y];
else
{
j++;
for(i=0;i<31;i++)if((1<<i)&W[y])bit[i]++;
}
}
for(i=0;i<31;i++)
{
if(2*bit[i]>j)ans2+=(1<<i)*(j-bit[i]),ans1+=(1<<i);
else ans2+=(1<<i)*bit[i];
}
printf("%lld\n%lld\n",ans2,ans1);
}

C++14(g++5.4) 解法, 执行用时: 3ms, 内存消耗: 504K, 提交时间: 2020-08-28 15:40:42

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=510;
int n,m,cnt[N],w[N],res,s,num,now;
void ins(int x){
num++;
for(int i=30;i>=0;i--) if(x>>i&1) cnt[i]++;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i],s+=w[i];
for(int i=1,a,b;i<=m;i++){
cin>>a>>b;
if(w[a]==-1) ins(w[b]);
else if(w[b]==-1) ins(w[a]);
else res+=w[a]^w[b];
}
for(int i=30;i>=0;i--)
if(cnt[i]*2>num) res+=(num-cnt[i])*(1LL<<i),now|=(1LL<<i);
else res+=cnt[i]*(1LL<<i);
cout<<res<<endl<<s+now+1<<endl;
return 0;
}

上一题