SRM 661 #DIV2

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;
   }
};
时间: 2024-08-08 01:16:28

SRM 661 #DIV2的相关文章

Floyd-Warshall+二进制枚举SRM 661 Div2 Medium: BridgeBuilding

SRM 661-Medium: BridgeBuildingDiv2  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

DP SRM 661 Div2 Hard: ColorfulLineGraphsDiv2

Problem Statement Bob is going to create a graph with N nodes. The graph will be constructed in two steps. First, Bob will take N isolated vertices, label them 1 through N and color each of them using one of K colors. Then, Bob will add some directed

topcoder SRM 618 DIV2 WritingWords

只需要对word遍历一遍即可 int write(string word) { int cnt = 0; for(int i = 0 ; i < word.length(); ++ i){ cnt+=word[i]-'A'+1; } return cnt; } topcoder SRM 618 DIV2 WritingWords,布布扣,bubuko.com

topcoder SRM 618 DIV2 MovingRooksDiv2

一开始Y1,Y2两个参数看不懂,再看一遍题目后才知道,vector<int>索引代表是行数,值代表的是列 此题数据量不大,直接深度搜索即可 注意这里深度搜索的访问标识不是以前的索引和元素,而是一个交换元素后的整个状态vector<int>,这样可以避免重复元素的搜索 set<vector<int> > visit; bool flag; void dfs(vector<int>& src, vector<int>& d

topcoder SRM 618 DIV2 LongWordsDiv2

此题给出的条件是: (1)word的每个字母都是大写字母(此条件可以忽略,题目给的输入都是大写字母) (2) 相等字符不能连续,即不能出现AABC的连续相同的情况 (3)word中不存在字母组成xyxy的形式,即不存在第一个字符和第3个字符相等同时第2个字符和第4个字符相等的情况 对于第(2)种情况,只需要考虑word[i]!=word[i-1]即可 对于第(3)种情况,用一个4重循环遍历每种可能的情况,然后第一个字符和第3个字符相等同时第2个字符和第4个字符相等,则输出“DisLikes”即可

TOPCODER SRM 686 div2 1000

// TOPCODER SRM 686 div2 1000 Problem Statement 给出一个至多长 100 的字符串,仅包含 ( 和 ),问其中有多少个不重复的,合法的括号子序列. 子序列可以不连续:合法即括号序列的合法:答案模 1,000,000,007. Examples "(())(" Returns: 2 Correct non-empty bracket subsequences are "()" and "(())". &

SRM 628 DIV2

250  想想就发现规律了. 500  暴力,括号匹配. 1000 给一个f数组,如果i存在,那么f[i]也得存在,问这样的集合有多少种. 先拓扑一下,dp[i] = mul(dp[son]+1)最后环里面的元素的乘积是结果. #include <iostream> #include <cstdio> #include <string> #include <algorithm> #include <stdlib.h> #include <v

topcoder srm 628 div2 250 500

做了一道题,对了,但是还是掉分了. 第二道题也做了,但是没有交上,不知道对错. 后来交上以后发现少判断了一个条件,改过之后就对了. 第一道题爆搜的,有点麻烦了,其实几行代码就行. 250贴代码: 1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 #include <cmath> 5 #include <cstdio> 6 #include <algorithm&g

topcoder SRM 619 DIV2 GoodCompanyDivTwo

注意题目给的最后一句话,如果部门任何employee都做不同类型的工作,则这个部门是一个diverse,题目是计算department的diverse数 读起来感觉有点别扭,英语没学好的原因 int countGood(vector <int> superior, vector <int> workType) { int res = 0; for(int i = 0 ; i < superior.size(); ++ i){ set<int> department