问题描述
由1对括号,可以组成一种合法括号序列: ()。
由2对括号,可以组成两种合法括号序列: ()(),(())。由4对括号组成的合法括号序列一共有多少种?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的多余的内容将无法得分。
思路:
括号对的合法序列,已经插入的左括号的数目大于等于右括号的数目。
(1)插入左括号:剩余的括号中,还有左括号;
(2)插入右括号:剩余的括号中,右括号的数目大于左括号的数目;
答案:14
代码:
其实这个递归中的r>l可以替换成r>1,因为此代码是优先摆放左括号,在第一次(((())))进行完往外跳出时,进入递归函数还是先看是否还有左括号,有就先添加左括号!有点类似于子集树,每个位置也是要么左括号,要么是右括号!然后在搜索之前加上符合本题的限定条件就ok了!!!
可以参考这篇文章(戳这里!)
public class Main1 {
static int num=0;
public static void printPar(int l, int r, char[] str, int count){
if(l<0 || r0){
str[count]='(';
printPar(l-1, r, str, count+1);
}
if(r>l){//注意是>l,不是>1,即剩余右括号的数量大于左括号的数量
str[count]=')';
printPar(l, r-1, str, count+1);
}
}
}
public static void main(String[] args){
int count = 4;
char str[] = new char[count*2];
printPar(count, count, str, 0);
System.out.println(num);
}
}
(((())))
((()()))
((())())
((()))()
(()(()))
(()()())
(()())()
(())(())
(())()()
()((()))
()(()())
()(())()
()()(())
()()()()
14
通过第一次跳出(第一行到第二行的转变也易知),一直往上跳出直到遇到有左括号,可以自己画一棵简单的两对括号的二叉树加深以下理解,易知2对括号就两条路可走。
题意:
从(1,1)走到(m,n),最大移动距离为d(d>=1),求最少移动次数
第一行输入m和n,第二行输入d
输入样例:
3 4
1.5
输出样例:
3
自己当时做的时候是直接分情况讨论了,先斜着走,再直着走,不知道对不对。
借鉴大佬的dfs代码如下:
15 15
1.4 会超时,不会宽搜,宽搜好像不超时
import java.util.Scanner;
public class Main {
static int m,n;
static double d;
static int min=Integer.MAX_VALUE;
static void dfs(int x,int y,int step){//利用step记录每个可行解的走的步数
if(x>m||y>n||step>min){//没有到达(m,n)点或者走到这的步数已经比已知的最少的步数多了,则不再往下搜索
return;
}
else if(x==m&&y==n&&step根号2时,可以斜着走
for(int i=0;i<=d;i++){
for(int j=0;j<=d;j++){
if((i*i+j*j)>0&&(i*i+j*j)<=d*d){
/*此处不能是step++或者++step,因为从每个点出发的下一步可能有三种选择
所以step不能改变,只能传参step+1
*/
dfs(x+i,y+j,step+1);
}
}
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner in=new Scanner(System.in);
m=in.nextInt();
n=in.nextInt();
d=in.nextDouble();
dfs(1,1,0);
System.out.println(min);
}
}
问题描述
小明有一块空地,他将这块空地划分为 n 行 m 列的小块,每行和每列的长度都为 1。
小明选了其中的一些小块空地,种上了草,其他小块仍然保持是空地。
这些草长得很快,每个月,草都会向外长出一些,如果一个小块种了草,则它将向自己的上、下、左、右四小块空地扩展,这四小块空地都将变为有草的小块。
请告诉小明,k 个月后空地上哪些地方有草。
输入格式
输入的第一行包含两个整数 n, m。
接下来 n 行,每行包含 m 个字母,表示初始的空地状态,字母之间没有空格。如果为小数点,表示为空地,如果字母为 g,表示种了草。
接下来包含一个整数 k。
输出格式
输出 n 行,每行包含 m 个字母,表示 k 个月后空地的状态。如果为小数点,表示为空地,如果字母为 g,表示长了草。
样例输入
4 5
.g...
.....
..g..
.....
2
样例输出
gggg.
gggg.
ggggg
.ggg.
评测用例规模与约定
对于 30% 的评测用例,2 <= n, m <= 20。
对于 70% 的评测用例,2 <= n, m <= 100。
对于所有评测用例,2 <= n, m <= 1000,1 <= k <= 1000。
JAVA
递归。。。刷题量不多就是不行,当时第一反应并查集可不可以做,因为前一天晚上刚好看了看并查集,再一看好像直接暴力就行,于是我就开始暴力到最后结束。。
暴力的话写了三重for循环,但是结果竟然从第一天就全是g了,一想是因为for是遍历了每个点,有的点刚被扩散长出草来又因为遍历到它,它又开始向四周扩散,所以才会将正片空地全部种上草!!!
于是我又想设一个note数组来记录每天向四周扩展的空地,无奈打表查看第一天对了,第二天又不对了。
晚上在想用递归试试,然后就过了。。用递归直接从每个初始种草点开始扩散就行,简单易懂
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
static int k,n,m;//扩散 k次
static void dfs(String[][] a,int i,int j,int count){
if(count>k){//每块种草的空地从开始到结束只扩展k天!!!
return;
}
if(j-1>=0){
a[i][j-1]="g";
dfs(a,i,j-1,count+1);
}
if(j+1=0){
a[i-1][j]="g";
dfs(a,i-1,j,count+1);
}
if(i+1 list=new ArrayList();//横坐标
ArrayList list1=new ArrayList();//纵坐标
//将最初种草的那几块空地坐标保存就行
for(int i=0;i