1. 程式人生 > >【題解】英雄數組

【題解】英雄數組

分享 clas == ring class turn show 程序 改變

題目描述

  英雄有兩個數組A和B,兩個數組的長度相同。英雄想要改變A,使得A和B距離盡量小。兩個數組的距離指的是A和B有多少個對應位上的數字不相同。
  英雄有一堆板子,每個板子上面有一個數字,恰好可以遮擋數組的一個位置。英雄需要把這堆板子全用完,並且數組的同一個位置最多只能放一個板子。
  求最小的距離。

輸入輸出格式

輸入格式

  第一行為數據組數。
  對於每組數據:
  第一行為兩個正整數N,M。表示數組A和B的長度以及板子的數量。 1 <= M <= N <= 50
  第二行N個正整數為A數組。
  第三行N個正整數為B數組。
  第四行M個正整數為板子。
  每個數字都不超過1000。

輸出格式

  對於每組數據,一行一個整數表示最小距離。

輸入輸出樣例

輸入樣例

3
3 1
1 1 1
2 2 2
2
3 0
1 2 3
3 2 1

3 3
2 2 2
2 2 2
1 2 3

輸入樣例

2
2
2

題解

  很明顯的t貪心:先盡可能把數字不相同的位置覆蓋成相同的,再把數字相同的位置覆蓋成相同的,最後盡可能把剩下的數字不相同的位置覆蓋成不相同的,剩下的就只能把數字相同的位置覆蓋成不相同的。

技術分享圖片
#include <iostream>
#include <cstdio>
#include <cstring>

#define
MAX_N (1000 + 5) #define MAX_M (1000 + 5) #define NUMBER (1000 + 5) using namespace std; int G; int n, m; int a[MAX_N], b[MAX_N]; int c[NUMBER]; int ans; int main() { scanf("%d", &G); int tmp, tot; while(G--) { memset(c, 0, sizeof c); scanf("%d%d", &n, &m); ans
= n; tot = 0; for(register int i = 1; i <= n; ++i) { scanf("%d", a + i); } for(register int i = 1; i <= n; ++i) { scanf("%d", b + i); if(a[i] == b[i]) --ans; else ++tot; } for(register int i = 1; i <= m; ++i) { scanf("%d", &tmp); ++c[tmp]; } for(register int i = 1; i <= n; ++i) { if(a[i] != b[i] && c[b[i]]) { --c[b[i]]; --tot; --m; --ans; } } for(register int i = 1; i <= n; ++i) { if(a[i] == b[i] && c[b[i]]) { --c[b[i]]; --m; } } printf("%d\n", ans + max(0, m - tot)); } return 0; }
參考程序

【題解】英雄數組