SRM 661 #DIV2

来源:互联网 发布:贵州省望谟县人口数据 编辑:程序博客网 时间:2024/06/05 16:55

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:FallingSandMethod:simulateParameters:vector <string>Returns:vector <string>Method signature:vector <string> simulate(vector <string> board)(be sure your method is public)

Limits

 Time limit (s):2.000Memory limit (MB):256Stack 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 andb, 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:BridgeBuildingDiv2Method:minDiameterParameters:vector <int>, vector <int>, intReturns:intMethod signature:int minDiameter(vector <int> a, vector <int> b, int K)(be sure your method is public)

Limits

 Time limit (s):2.000Memory limit (MB):256Stack 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 throughN 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:ColorfulLineGraphsDiv2Method:countWaysParameters:int, intReturns:intMethod signature:int countWays(int N, int K)(be sure your method is public)

Limits

 Time limit (s):2.000Memory limit (MB):256Stack 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;   }};


0 0