【題解】英雄數組
阿新 • • 發佈:2019-03-24
分享 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; }
【題解】英雄數組