蓝桥杯第八届省赛

第4题

标题:方格分割

6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如图:p1.png, p2.png, p3.png 就是可行的分割法。
试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。

请提交该整数,不要填写任何多余的内容或说明文字。

图的dfs

按照两部分分割开的线深度搜索

vis[7][7]存放0/1,表示是否访问过结点(图中的十字)

#include<bits/stdc++.h>
using namespace std;
int vis[7][7];
int d_x[4]={0,0,1,-1};
int d_y[4]={1,-1,0,0};
int ans=0;
void dfs(int x,int y){
	if(x==0||y==0||x==6||y==6){
		ans++;
		return;
	}
	for(int i=0;i<4;i++){        //dx,dy表示搜索的下一个点;fx,fy表示该点的旋转对称点
		int dx=x+d_x[i];
		int dy=y+d_y[i];
		if(vis[dx][dy]==0){
			int fx=6-x;
			int fy=6-y;
			vis[dx][dy]=vis[fx][fy]=1;
			dfs(dx,dy);
			vis[dx][dy]=vis[fx][fy]=0; 
		}
	}
}
int main() {
	memset(vis,0,sizeof(vis));
	vis[3][3]=1;
	dfs(3,3);
	cout<<ans/4<<endl;            //dxdy向 上下左右 四个方向的搜索形状一样,ans重复算了4次,因此要除4
    return 0;
}

第5题

 

标题:字母组串

由 A,B,C 这3个字母就可以组成许多串。
比如:"A","AB","ABC","ABA","AACBB" ....
现在,小明正在思考一个问题:
如果每个字母的个数有限定,能组成多少个已知长度的串呢?
他请好朋友来帮忙,很快得到了代码,
解决方案超级简单,然而最重要的部分却语焉不详。
请仔细分析源码,填写划线部分缺少的内容。

对于上面的测试数据,小明口算的结果应该是:
6
19

注意:只填写划线部分缺少的代码,不要提交任何多余内容或说明性文字。

#include<bits/stdc++.h>
using namespace std;
int f(int a, int b, int c, int n)
{
	if(a<0 || b<0 || c<0) return 0;
	if(n==0) return 1; 
	
	return f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1);  // 填空
}

int main()
{
	printf("%d\n", f(1,1,1,2));
	printf("%d\n", f(1,2,3,3));
	return 0;
}
f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1);  // 填空
}

int main()
{
	printf("%d\n", f(1,1,1,2));
	printf("%d\n", f(1,2,3,3));
	return 0;
}

第6题

标题:最大公共子串
最大公共子串长度问题就是:
求两个串的所有子串中能够匹配上的最大长度是多少。
比如:"abcdkkk" 和 "baabcdadabc",
可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。
下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。
 

请分析该解法的思路,并补全划线部分缺失的代码。

#include<bits/stdc++.h>
using namespace std;
#define N 256
int f(const char* s1, const char* s2)
{
	int a[N][N];
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int i,j;
	
	memset(a,0,sizeof(int)*N*N);
	int max = 0;
	for(i=1; i<=len1; i++){
		for(j=1; j<=len2; j++){
			if(s1[i-1]==s2[j-1]) {
				a[i][j] = a[i-1][j-1]+1;  //填空
				if(a[i][j] > max) max = a[i][j];
			}
		}
	}
	
	return max;
}

int main()
{
	printf("%d\n", f("abcdkkk", "baabcdadabc"));
	return 0;
}a[i-1][j-1]+1;  //填空
				if(a[i][j] > max) max = a[i][j];
			}
		}
	}
	
	return max;
}

int main()
{
	printf("%d\n", f("abcdkkk", "baabcdadabc"));
	return 0;
}

???没懂,当是s1[i-1]!=s2[j-1]时,a[i][j]还是初始化的0啊,那么s1[i-1]!=s2[j-1]时,a[i-1][j-1]也有可能是初始化的0呀??

第7题

描述:正则问题
考虑一种简单的正则表达式:
只由 x ( ) | 组成的正则表达式。
小明想求出这个正则表达式能接受的最长字符串的长度。  
例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是: xxxxxx,长度是6。
输入
----
一个由x()|组成的正则表达式。输入长度不超过100,保证合法。  
输出
----
这个正则表达式能接受的最长字符串的长度。  
例如,
输入:
((xx|xxx)x|(x|xx))xx  
程序应该输出:
6  
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值