码迷,mamicode.com
首页 > 其他好文 > 详细

SRM 661 #DIV2

时间:2015-06-15 00:19:35      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:

Problem Statement

 

You have a rectangular board that is placed vertically. The board is divided into a grid of unit square cells. Some grid cells contain obstacles and some cells contain a grain of sand. All other cells are currently empty.

You are given the description of the board as a String[] board. The elements ofboard correspond to rows of the grid in the order from top to bottom. (E.g.,board[0] represents the topmost row of cells.) Each character in each element ofboard represents one cell. The character ‘x‘ represents a cell with an obstacle, ‘o‘ is a grain of sand, and ‘.‘ (period) is an empty cell.

You would like to implement a simulation of falling sand. The rules are as follows:

  • The obstacles don‘t move.
  • Whenever there is an empty cell immediately below a grain of sand, the grain of sand moves into the empty cell.

Return the final configuration of the board after all grains of sand reach their final locations.

Definition

 
Class: FallingSand
Method: simulate
Parameters: vector <string>
Returns: vector <string>
Method signature: vector <string> simulate(vector <string> board)
(be sure your method is public)

Limits

 
Time limit (s): 2.000
Memory limit (MB): 256
Stack limit (MB): 256

Constraints

- board will contain between 1 and 50 elements, inclusive.
- Each element of board will have length between 1 and 50, inclusive.
- All elements of board will have the same length.
-

Each character in each element of board will be one of ‘x‘, ‘o‘, and ‘.‘


题意:模拟过程。(250分)

题解:具体就是如果上面一层有o,且当前层为.就一直做下去。

#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <functional>
#include <algorithm>
typedef long long LL;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int,int>pil;

class FallingSand {
public:
   vector <string> simulate( vector <string> board ) {
        int n=board.size();
        int m=board[0].size();
        int flag=1;
        while(flag)
        {
            flag=0;
            for(int i=1;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    if(board[i-1][j]=='o'&&board[i][j]=='.')
                    {
                        board[i-1][j]='.';
                        board[i][j]='o';
                        flag=1;
                    }
                }
            }
        }
        return board;
   }
};

Problem Statement

 

You have two rows of nodes. Each row contains N nodes, numbered 0 through N-1 from the left to the right.

Within each row, adjacent nodes are already connected by edges. You are given the lengths of these edges as vector <int>sa and b, each containing N-1 elements. For each valid i,a[i] is the length of the edge between nodes i and (i+1) in the top row, andb[i] is the length of the edge between nodes i and (i+1) in the bottom row.

You want to add exactly K new edges to this graph. Each of the new edges must be vertical -- i.e., it must connect some vertex i in the top row to the vertex i in the bottom row. All new edges will have length 0.

By adding the K new edges we will produce a connected graph. The diameter of this graph is the maximum of all shortest distances among pairs of its nodes. In other words, the diameter is the smallest number D such that it is possible to travel from any node to any other node using a path of length D or less.

Given a, b, and the int K, compute and return the smallest possible diameter of the resulting graph.

Definition

 
Class: BridgeBuildingDiv2
Method: minDiameter
Parameters: vector <int>, vector <int>, int
Returns: int
Method signature: int minDiameter(vector <int> a, vector <int> b, int K)
(be sure your method is public)

Limits

 
Time limit (s): 2.000
Memory limit (MB): 256
Stack limit (MB): 256

Constraints

- N will be between 2 and 11, inclusive.
- a,b will contain exactly N-1 elements each.
- K will be between 1 and N, inclusive.
- Each element of a,b will be between 1 and 50, inclusive.

题意:上下两行,每行相邻有路径,然后让你在上下两行加权值为0的边问你两点的最短路径最长为多少。(500分)

题解:n太小,直接状压跑floyd即可。

#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <functional>
#include <algorithm>
typedef long long LL;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int,int>pil;
int mp[30][30],m[30][30],ans,n,N;
void floyd()
{
    for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
          m[i][j]=mp[i][j];
    for(int k=0;k<N;k++)
        for(int i=0;i<N;i++)
          for(int j=0;j<N;j++)
            m[i][j]=min(m[i][j],m[i][k]+m[k][j]);
    int s=0;
    for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
          s=max(s,m[i][j]);
    ans=min(ans,s);
}
class BridgeBuildingDiv2 {
public:
   int minDiameter( vector <int> a, vector <int> b, int K ) {
        n=a.size()+1;
        N=n*2;
        CLEAR(mp,INF);
        ans=INF;
        for(int i=0;i<n-1;i++)
            mp[i][i+1]=mp[i+1][i]=a[i];
        for(int i=0;i<n-1;i++)
            mp[n+i][n+1+i]=mp[n+1+i][n+i]=b[i];
        for(int i=0;i<N;i++)
            mp[i][i]=0;
        int st=(1<<n)-1;
        for(int i=0;i<=st;i++)
        {
            int cnt=0;
            for(int j=0;j<n;j++)
               if(i&(1<<j)) cnt++;
            if(cnt==K)
            {
                for(int j=0;j<n;j++)
                    if(i&(1<<j))
                        mp[j][j+n]=mp[j+n][j]=0;
                floyd();
                for(int j=0;j<n;j++)
                    if(i&(1<<j)) mp[j][j+n]=mp[j+n][j]=INF;
            }
        }
        return ans;
   }
};

Problem Statement

 

Bob is going to create a graph with N nodes. The graph will be constructed in two steps. First, Bob will takeN isolated vertices, label them 1 through N and color each of them using one ofK colors. Then, Bob will add some directed edges to the graph. For each i between 2 andN, inclusive, Bob may choose a single value j < i such that the nodes i and j have different colors. If he does, he will add the edge from i to j to his graph. Note that Bob may choose not to add any edge from node i, even if there are some valid choices of j.

Two graphs are considered the same if they have the same node colors and the same set of edges.

You are given the ints N and K. Compute and return the number of different graphs Bob may construct, modulo 1,000,000,007.

Definition

 
Class: ColorfulLineGraphsDiv2
Method: countWays
Parameters: int, int
Returns: int
Method signature: int countWays(int N, int K)
(be sure your method is public)

Limits

 
Time limit (s): 2.000
Memory limit (MB): 256
Stack limit (MB): 256

Constraints

- N will be between 1 and 100, inclusive.
- K will be between 1 and 3, inclusive
题意:就是给你K中颜色,然后N的节点,问你给每个节点涂色,颜色不同节点可以连边。

问你方案数。(950分)

题解:方案数比较蛋疼。开始dp[i][j]代表前i个节点,且第i个节点图第j种颜色的方案数。

dp[i][j]+=dp[i-1][k](没有从i节点出发的边)

dp[i][j]+=(dp[p][k])(k!=j)(从i节点出发的边)

结果发现少了好多,最后在N=3,K=2研究了下,发现递推的方程应该在第i-1的地方转移。

#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <functional>
#include <algorithm>
typedef long long LL;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int,int>pil;
const int mod=1e9+7;
LL dp[110][5];
class ColorfulLineGraphsDiv2 {
public:
   int countWays( int N, int K ) {
      CLEAR(dp,0);
      for(int i=0;i<K;i++)
         dp[1][i]=1;
      for(int i=2;i<=N;i++)
      {
           for(int j=0;j<K;j++)
           {
               for(int k=0;k<K;k++)
                  dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;//不连线
               for(int p=1;p<i;p++)
               {
                   for(int kk=0;kk<K;kk++)
                     if(kk!=j) dp[i][j]=(dp[i][j]+dp[i-1][kk])%mod;
               }
           }
      }
      LL ans=0;
      for(int i=0;i<K;i++)
        ans=(ans+dp[N][i])%mod;
      return ans;
   }
};


SRM 661 #DIV2

标签:

原文地址:http://blog.csdn.net/u013582254/article/details/46495755

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!