SRM593(1-250pt,500pt)
SRM 593
DIV1 250pt
题意:有如下图所示的平面,每个六边形有坐标。将其中一些六边形染色,要求有边相邻的两个六边形不能染同一种颜色。给定哪些六边形需要染色,问最少需要多少种颜色。
解法:首先,需要0种颜色和需要1种颜色很容易判断,其次,最多需要3种颜色。易证。
也就是说,难以判断的就是需要2种颜色还是3种颜色。假定只需要染2种颜色,然后将需要染色的六边形染色,看是否会出现矛盾。用DFS染色。
Ps:和官方题解一比,自己写的代码太麻烦了....
tag:染色
1 /* 2 * Author: plum rain 3 * score : 0 4 */ 5 #line 11 "HexagonalBoard.cpp" 6 #include <sstream> 7 #include <stdexcept> 8 #include <functional> 9 #include <iomanip> 10 #include <numeric> 11 #include <fstream> 12 #include <cctype> 13 #include <iostream> 14 #include <cstdio> 15 #include <vector> 16 #include <cstring> 17 #include <cmath> 18 #include <algorithm> 19 20 using namespace std; 21 22 23 typedef vector<string> VS; 24 VS b; 25 int n, ans, col[55][55]; 26 27 void DFS (int x, int y, int c) 28 { 29 if (!(b[x][y] == 'X' && col[x][y] == -1)) return ; 30 col[x][y] = c; 31 ans = max(ans, 1); 32 for (int i = max(0, x-1); i <= min(n-1, x+1); ++ i) 33 for (int j = max(0, y-1); j <= min(n-1, y+1); ++ j){ 34 if (i-x != j-y && b[i][j] == 'X'){ 35 DFS (i, j, !c); 36 ans = max(2, ans); 37 if (col[i][j] == c){ 38 ans = 3; 39 return ; 40 } 41 } 42 } 43 } 44 45 class HexagonalBoard 46 { 47 public: 48 int minColors(vector <string> board){ 49 b.clear(); b = board; 50 n = b.size(); 51 ans = 0; 52 memset (col, -1, sizeof(col)); 53 54 for (int i = 0; i < n; ++ i) 55 for (int j = 0; j < n; ++ j){ 56 DFS (i, j, 0); 57 if (ans == 3) return 3; 58 } 59 60 return ans; 61 } 62 };
DIV1 450pt
题意:有n只兔子,每只兔子跑一圈的时间在范围a[i] ~ b[i]。将兔子分为两组S和T,每只兔子分别跑一圈,每组所用时间等于该组所有兔子消耗时间之和。每组可能的所用时间之差的最大值为x。求x的最小值。
解法:记A为所有a[i]的和,B为所有b[i]的和,记sum = A + B。记所有属于T的兔子的a[i]之和t_a,b[i]之和为t_b,所有属于S的兔子的a[i]之和s_a,b[i]之和为s_b。
每次将兔子分为两组之后,时间之差的最大值为max (t_b - s_a, s_b - t_a)或者max (s_b - t_a, s_b - t_a)。由于考虑到T和S是地位对等的,即如果存在T = {1,3},S = {2}的情况,也一定存在T = {2}, S = {1, 3}的情况。所以只需要求max (t_b - s_a, s_b - t_a)即可。
max (t_b - s_a, s_b - t_a) = max (t_b - (A-t_a), (B-t_b) - t_a) = max ((t_a+t_b) - A, sum - A - (t_a+t_b)),且要使max值尽量小,则t_a + t_b 尽量接近于sum/2即可。(注意sum和A都是固定值)
也就是说,先用一次动态规划处理出t_a + t_b的所有可能值,然后再找最接近sum/2的一个即可。
tag:math, dp, think, good
1 /* 2 * Author: plum rain 3 * score : 0 4 */ 5 #line 11 "MayTheBestPetWin.cpp" 6 #include <sstream> 7 #include <stdexcept> 8 #include <functional> 9 #include <iomanip> 10 #include <numeric> 11 #include <fstream> 12 #include <cctype> 13 #include <iostream> 14 #include <cstdio> 15 #include <vector> 16 #include <cstring> 17 18 using namespace std; 19 20 #define CLR(x) memset(x, 0, sizeof(x)) 21 #define out(x) cout<<#x<<":"<<(x)<<endl 22 #define tst(a) cout<<#a<<endl 23 24 const int maxx = 1000000; 25 bool dp[maxx+5]; 26 27 class MayTheBestPetWin 28 { 29 public: 30 int calc(vector <int> A, vector <int> B){ 31 CLR (dp); dp[0] = 1; 32 int sum = 0, ta = 0; 33 for (int i = 0; i < A.size(); ++ i){ 34 int s = A[i] + B[i]; 35 sum += s; ta += A[i]; 36 for (int j = maxx-s; j >= 0; -- j) 37 if (dp[j]) dp[j+s] = 1; 38 } 39 int half = sum / 2; 40 while (!dp[half]) -- half; 41 return (sum - ta - half); 42 } 43 };
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。