zoukankan      html  css  js  c++  java
  • Topcoder SRM 637 (Div.2)

    A.GreaterGameDiv2

    不能更水

     1 #line 7 "GreaterGameDiv2.cpp"
     2 #include<cstdio>
     3 #include <cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<iostream>
     7 #include<algorithm>
     8 #include<set>
     9 #include<map>
    10 #include<stack>
    11 #include<string>
    12 #include <ctime>
    13 #include<vector>
    14 #include<queue>
    15 #include <cctype>
    16 #include<sstream>
    17 #define eps 0.000001
    18 #define ALL(x) x.begin(),x.end()
    19 #define INS(x) inserter(x,x.begin())
    20 #define clr(x,a) memset(x,a,sizeof(x))
    21 #define sz(x) (int)x.size()
    22 #define pb push_back
    23 #define mp make_pair
    24 using namespace std;
    25 typedef long long LL;
    26 int n,m;
    27 class GreaterGameDiv2
    28 {    
    29     public:
    30     int calc(vector <int> s, vector <int> t)
    31     {
    32         int i,j,k;
    33         int ans=0;
    34         for (i=0;i<s.size();i++)
    35         {
    36             if (s[i]>t[i]) ans++;
    37         }
    38         return ans;
    39     }
    40 };
    View Code

    B.PathGameDiv2

    贪心策略,使得这条路转完次数尽量小(因为转一次就多占一个格子),那么主人公一直往前走,直到遇见墙才转弯,求出路径再求答案就容易了。注意要枚举一下起始点,可以是第一行,也可以是第二行

     1 #include<cstdio>
     2 #include <cstdlib>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<set>
     8 #include<map>
     9 #include<stack>
    10 #include<string>
    11 #include <ctime>
    12 #include<vector>
    13 #include<queue>
    14 #include <cctype>
    15 #include<sstream>
    16 #define eps 0.000001
    17 #define ALL(x) x.begin(),x.end()
    18 #define INS(x) inserter(x,x.begin())
    19 #define clr(x,a) memset(x,a,sizeof(x))
    20 #define sz(x) (int)x.size()
    21 #define pb push_back
    22 #define mp make_pair
    23 using namespace std;
    24 typedef long long LL;
    25 int n,m;
    26 class PathGameDiv2
    27 {
    28     public:
    29     int calc(vector <string> board)
    30     {
    31         int i,j,k;
    32         string a=board[0],b=board[1];
    33         int len=a.size();
    34         int flag=0;
    35         int ans=0;
    36         if (board[0][0]=='.')
    37         {
    38 
    39             for (i=0;i<len;i++)
    40             {
    41                 if (i!=len-1&&board[flag][i+1]=='#')
    42                 {
    43                     flag=!flag;
    44                 }else
    45                 if (board[flag^1][i]=='.')
    46                 {
    47                     ans++;
    48                 }
    49             }
    50         }
    51         int ans2=0;
    52         if (board[1][0]=='.')
    53         {
    54             flag=1;
    55             for (i=0;i<len;i++)
    56             {
    57                 if (i!=len-1&&board[flag][i+1]=='#')
    58                 {
    59                     flag=!flag;
    60                 }else
    61                 if (board[flag^1][i]=='.')
    62                 {
    63                     ans2++;
    64                 }
    65             }
    66         }
    67         return max(ans,ans2);
    68     }
    69 };
    View Code

    C.ConnectingGameDiv2

    给一个n*m(均小于等于50)的地图,图中用不同的符号划分为多个区域,每个区域中 相邻点一定有一个公共边,

    现有一个标记操作,一次标记只能标记一个区域中的全部点,

    求至少标记多少个(注意是点) 使得不存在一条路径,从图最上端沿未标记点走到地图最下端。

    最短路径问题

    首先是构图,每一块区域可以化为一个点,点的权值是这个区域的面积,然后对于区域i,如果区域j与之相邻①,则从图中的点i向点j连一条边,

    这样现在问题就转化为:从原地图最左端开始到最右端结束,选一条路径,且点权值和最小。

    1.这是多起点,多终点的问题,所以需要添加一个虚拟的起点与终点,虚拟起点与各个起点连一条边,各个终点与虚拟起点连一条边

    2.将点权化为边权,对于点i,我们将以点i为起点边的权值规定为点的权值。

    因为点数并不是很多,跑一发弗洛伊德算法即可。

    注意这道题有一个神奇的坑点:所选的区域并不一定是相邻的,比如说这样:

    显然这样也是满足题意的,也就是说我们需要定义另一种区域相邻,即在八个相邻即可,而不是原来的四个方向相邻。

     1 #include<cstdio>
     2 #include <cstdlib>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<set>
     8 #include<map>
     9 #include<stack>
    10 #include<string>
    11 #include <ctime>
    12 #include<vector>
    13 #include<queue>
    14 #include <cctype>
    15 #include<sstream>
    16 #define eps 0.000001
    17 #define ALL(x) x.begin(),x.end()
    18 #define INS(x) inserter(x,x.begin())
    19 #define clr(x,a) memset(x,a,sizeof(x))
    20 #define sz(x) (int)x.size()
    21 #define pb push_back
    22 #define mp make_pair
    23 using namespace std;
    24 typedef long long LL;
    25 int n,m;
    26 class ConnectingGameDiv2
    27 {
    28     int dis[260][260],sum[260],start,finish,left,right;
    29     vector <string> grid;
    30     public:
    31     void addedge(int i,int j,int x, int y)
    32     {
    33         if (x<0||y<0||x>=n||y>=m) return;
    34         int a=(int)grid[i][j];
    35         int b=(int)grid[x][y];
    36         dis[a][b]=min(dis[a][b],sum[a]);
    37         dis[b][a]=min(dis[b][a],sum[b]);
    38     }
    39     
    40     int getmin(vector <string> board)
    41     {
    42         grid=board;
    43         int i,j,k;
    44         n=board.size();
    45         m=board[0].size();
    46         memset(sum,0,sizeof(sum));
    47         for (i=0;i<n;i++)
    48         {
    49             for (j=0;j<m;j++)
    50             {
    51                 sum[(int)board[i][j]]++;
    52             }
    53         }
    54         for (i=0;i<260;i++)
    55         {
    56             for (j=0;j<260;j++)
    57             {
    58                 dis[i][j]=100000;
    59             }
    60         }
    61         for (i=0;i<260;i++) dis[i][i]=0;
    62         start=0;
    63         finish=1;
    64         for (i=0;i<n;i++)
    65         {
    66             left=(int)board[i][0];
    67             right=(int)board[i][m-1];
    68             dis[start][left]=0;
    69             dis[right][finish]=sum[right];
    70         }
    71         for (i=0;i<n;i++)
    72         {
    73             for (j=0;j<m;j++)
    74             {
    75                 addedge(i,j,i+1,j);
    76                 addedge(i,j,i-1,j);
    77                 addedge(i,j,i,j+1);
    78                 addedge(i,j,i,j-1);
    79                 
    80                 addedge(i,j,i+1,j+1);
    81                 addedge(i,j,i-1,j-1);
    82                 addedge(i,j,i+1,j-1);
    83                 addedge(i,j,i-1,j+1);
    84             }
    85         }
    86         for (k=0;k<260;k++)
    87         {
    88             for (i=0;i<260;i++)
    89             {
    90                 for (j=0;j<260;j++)
    91                 {
    92                     if (i==j||j==k||i==k) continue;
    93                     dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    94                 }
    95             }
    96         }
    97         return dis[start][finish];
    98     }
    99 };
    View Code

    ==================================

    第一次用,TC客户端的插件,怎么说呢,相当方便。省去了每次粘类名的麻烦,它都给自动生成,而且测试也简单的多。

    总之这次比赛还算满意的,虽然比赛后仍是灰名,但rating涨了104,也是醉了,还没有绿名。

    这次写了两道题,第三道因为写的略微麻烦没有写完,嘛,反正最后也是参考了别人的代码才得以简化的。

    【一点经验】图论题目如果点少的话还是尽量用邻接矩阵,这样也不容易出错,代码写的也快,尤其是对TC这种短时间的比赛

  • 相关阅读:
    【C++clock()函数学习(计算自己代码运行时间)】
    YCOJ 1041113【最近的回文数】
    计蒜客【汉诺塔II】
    YCOJ【汉诺塔】
    【常用算法总结——递归】
    YCOJ【查找】
    【常用算法总结——分治】
    Redis哨兵机制
    Redis主从复制
    SpringBoot集成Redis
  • 原文地址:https://www.cnblogs.com/zhyfzy/p/4049224.html
Copyright © 2011-2022 走看看