第三题:
试题编号: | 201312-3 |
试题名称: | 最大的矩形 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是hi。这n个矩形构成了一个直方图。例如,下图中六个矩形的高度就分别是3, 1, 6, 5, 2, 3。 输入格式 第一行包含一个整数n,即矩形的数量(1 ≤ n ≤ 1000)。 输出格式 输出一行,包含一个整数,即给定直方图内的最大矩形的面积。 样例输入 6 样例输出 10 |
解题思路:
dp[i][j] 首先预处理出 从 i 开始 长度为 j 的最高值。
长度为1时:是每一位的值
dp[i][1]=cas[i];
长度大于1时:dp[i][j-1]与cas[i+j-1]比较得到
dp[i][j]=dp[i][j-1]<=cas[i+j-1]?dp[i][j-1]:cas[i+j-1];
其中 cas 为输入的一维数组 ,i+j-1<=n-1;
然后穷举 根据矩形的面积公式不断更新值,最终得到最大值。
参考代码:
#include<stdio.h>
int cas[1010];
int dp[1010][1010];
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&cas[i]);
}
for(int i=0;i<n;i++){
dp[i][1]=cas[i];
}
for(int j=2;j<=n;j++) {
for(int i=0;i+j<=n;i++){
dp[i][j]=dp[i][j-1]<=cas[i+j-1]?dp[i][j-1]:cas[i+j-1];
}
}
/* for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%d ",dp[i][j]);
}
puts("\n");
}
*/
int maxn=0;
for(int len=1;len<=n;len++){
for(int i=0;i+len-1<=n-1;i++){
maxn=len*dp[i][len]>maxn?len*dp[i][len]:maxn;
}
}
printf("%d",maxn);
return 0;
}
第四题:
试题编号: | 201312-4 |
试题名称: | 有趣的数 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 我们把一个数称为有趣的,当且仅当: 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000)。 输出格式 输出只有一行,包括恰好n 位的整数中有趣的数的个数除以1000000007的余数。 样例输入 4 样例输出 3 |
解题思路:
采用动态规划思想,每一次决策都基于前一次决策的最优解。
即对一个n位数的解都基于前一个n-1位的数的最优解。
我们对一个数的第n位规定一个状态集:即到这一位为止还有几个数字没有使用(我们有0123共四个数)。
根据规则来说,共有6种状态:
0--用了2,剩0,1,3
1--用了0,2,剩1,3
2--用了2,3,剩0,1
3--用了0,1,2,剩3
4--用了0,2,3,剩1
5--全部用了
于是我们需要让用户输入位数,然后声明同等位数的数组,在每个元素里是6种状态中所包含的该状态下的“符合条件的数”的个数。(是二维数组)
然后用动态规划思想从最小位数开始逐层往上计算。
状态图:
参考代码:
#include<stdio.h>
int main()
{
int i,n;
long long dp[1010][10];
scanf("%d",&n);
for (i=1;i<=n;i++)
{
dp[i][0]=1; //首位只能为2
dp[i][1]=(dp[i-1][1]*2+dp[i-1][0])%1000000007;
dp[i][2]=(dp[i-1][2]+dp[i-1][0])%1000000007;
dp[i][3]=(dp[i-1][3]*2+dp[i-1][1])%1000000007;
dp[i][4]=(dp[i-1][4]*2+dp[i-1][2]+dp[i-1][1])%1000000007;
dp[i][5]=(dp[i-1][5]*2+dp[i-1][4]+dp[i-1][3])%1000000007;
}
printf("%lld\n",dp[n][5]);
return 0;
}
第五题:
试题编号: | 201312-5 |
试题名称: | I’m stuck! |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思: 输入格式 输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。 输出格式 如果玩家在初始位置就已经不能到达终点了,就输出“I'm stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。 样例输入 5 5 样例输出 2 样例说明 如果把满足性质的方格在地图上用'X'标记出来的话,地图如下所示: |
解题思路:
dfs 遍历能够到达的点和能够到达终点的点,最终查找输出。
参考代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 55
using namespace std;
int r, c, s, e;
char cas[maxn][maxn];
bool f1[maxn][maxn], f2[maxn][maxn];
bool valiate(int x,int y){
if (x < 0 || x >= r || y < 0 || y >= c|| cas[x][y] == '#') return false;
return true;
}
void dfs1(int x, int y)
{
if(!valiate(x,y)||f1[x][y]) return ;
f1[x][y] = true;
if (cas[x][y] == '|') dfs1(x + 1, y), dfs1(x - 1, y);
else if (cas[x][y] == '-') dfs1(x, y - 1),dfs1(x, y + 1);
else if (cas[x][y] == '.')dfs1(x + 1, y);
else dfs1(x + 1, y), dfs1(x - 1, y), dfs1(x, y - 1), dfs1(x, y + 1);
}
void dfs2(int x,int y){
if(!valiate(x,y)||f2[x][y]) return;
f2[x][y] = true;
if(cas[x-1][y]=='+'||cas[x-1][y]=='|'||cas[x-1][y]=='.'||cas[x-1][y]=='S'||cas[x-1][y]=='T') dfs2(x-1,y);
if(cas[x+1][y]=='+'||cas[x+1][y]=='|'||cas[x+1][y]=='S'||cas[x+1][y]=='T') dfs2(x+1,y);
if(cas[x][y+1]=='+'||cas[x][y+1]=='-'||cas[x][y+1]=='S'||cas[x][y+1]=='T') dfs2(x,y+1);
if(cas[x][y-1]=='+'||cas[x][y-1]=='-'||cas[x][y-1]=='S'||cas[x][y-1]=='T') dfs2(x,y-1);
}
int main(){
scanf("%d %d",&r,&c);
char cc;
int si,sj,ti,tj;
for (int i = 0; i < r; i++){
for (int j = 0; j < c; j++){
scanf("\n%c",&cas[i][j]);
if(cas[i][j]=='S') si=i,sj=j;
if(cas[i][j]=='T') ti=i,tj=j;
}
}
// printf("%d %d %d %d\n",si,sj,ti,tj);
memset(f1,false,sizeof(f1));
memset(f2,false,sizeof(f2));
dfs1(si,sj),dfs2(ti,tj);
int sum = 0;
/*
for (int i = 0; i < r; i++){
for (int j = 0; j < c; j++)
printf("%d",f1[i][j]);
printf("\n");
}
for (int i = 0; i < r; i++){
for (int j = 0; j < c; j++)
printf("%d",f2[i][j]);
printf("\n");
} */
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
if (f1[i][j] && !f2[i][j]){
sum++;
//printf("%d %d\n",i,j);
}
if (f1[ti][tj]) printf("%d\n",sum);
else printf("I'm stuck!\n");
return 0;
}