2020.10.18 蓝桥杯省赛第五题:上升子串, 第九题:画中漂流

it2024-03-20  77

第一次参加蓝桥杯,大赛经验不是特别足,这两道题当时思路是对的,代码写一半,一些细节没处理好,没把答案算出来 。唉 下次继续加油吧!

1. 第五题 上升子串

count:当前连续上升的字母数量,n:它所要求的字母上升数量

#include<stdio.h> int sum=0; int dir[4][2]={0,-1,0,1,-1,0,1,0};//定义四个方向 void dfs(int i,int j,int count,char a[101][101],int n){ if(count==n) sum++;//当二者相等的时候,表示已经找到一个方案 else for(int ii=0;ii<4;ii++) if(a[i+dir[ii][0]][j+dir[ii][1]]>a[i][j]) dfs(i+dir[ii][0],j+dir[ii][1],++count,a,n),count--; } int main(){ char a[101][101]; for(int i=1;i<=100;i++) for(int j=1;j<=100;j++) scanf("%c",&a[i][j]); for(int n=1;n<=26;n++)//因为是字母,最大上升序列最多为26 for(int i=1;i<=100;i++) for(int j=1;j<=100;j++) dfs(i,j,1,a,n); printf("%d",sum); return 0; }

2. 第九题 画中漂流(两种解法)

解法一: i:等待救援秒数 j:剩余体力 分析题意发现答案与它离瀑布有多远没有关系,只要你保证不掉下去就行。dp[i][j]表示i秒j点体力的方案数量。思路:当2*t<j时很显然一直向前游也会掉下去,0种解法。当i=j时因为要把体力用完 只能选择一直向前游,一种解法。当i-1=j 第一秒只能选择向前游,不游的那一秒还剩i-1种选择空间,所以有i-1种解法。最后重要的转移方程来了 因为只能选择游与不游,不游的话就是秒数剩余i-1,体力剩余j,游的话秒数剩余i-1,体力剩余j-1。所以dp[i][j]=dp[i-1][j]+dp[i-1][j-1];

#include<stdio.h> int P=1000000007; int dp[101][101]; int main(){ int s,t,m; for(int i=1;i<=100;i++) for(int j=1;j<=i;j++){ if(j*2<i)// dp[i][j]=0; else if(i==j) dp[i][j]=1; else if(j==i-1) dp[i][j]=i-1; else dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%P; } scanf("%d %d %d",&s,&t,&m); printf("%d",dp[t][m]); return 0; }

解法二 用dfs来写,这道题用数学知识来想的话其实就是全排列,把划当成1,不划当成0,m就是总秒数,t就是划的次数。sum1表示当前划的次数和,sum2表示当前不划的次数和,只要划的次数大于不划的次数就不会掉下去,当sum1+sum2=m并且sum1=t时找到一种解法。

#include<stdio.h> int t,m,s,sum=0; void dfs(int m,int sum1,int sum2){ if(sum1<sum2||sum1+sum2>m){ } else if(sum1+sum2==m&&sum1==t){ sum++; sum%=P; } else for(int i=0;i<=1;i++){ if(i==0) dfs(m,sum1,sum2+1); else dfs(m,sum1+1,sum2); } } int main(){ scanf("%d%d%d",&s,&m,&t); dfs(m,0,0);//刚开始1和0个数均为0 printf("%d",sum); return 0; }
最新回复(0)