• 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 };
    View Code

    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 };
    View Code
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    小程序开发点滴积累
    使用openssl在windows 10下本地xampp配置https开发环境
    linux networking
    CGI,FastCGI,PHP-FPM,PHP-CLI,modPHP
    centos 7.2 64位 docker安装lamp环境
    反模拟类游戏外挂 转
    鼠标 hook 源码 C#版
    C# 鼠标连击源码 转
    win32 API 在win10 64位失效
    利用浏览器外部协议(URL Procotol)打开本地exe文件
  • 原文地址:https://www.cnblogs.com/plumrain/p/topcoder_srm_119.html
Copyright © 2020-2023  润新知