1396. 挖掘机(d)
(File IO): input:d.in output:d.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet
题目描述
挖掘机学校哪家强?中国山东找蓝翔。这几天,蓝翔技工学校在进行挖掘机比赛。比赛是这样进行的:一块场地被划分成了n*n个格子,每个学生要驾驶挖掘机不重复地开过每个格子,并且只允许在格子中间转弯。如下图,分别是4*4和3*3的情况:
每个学生只能从边界上的点进出比赛场地。并且,为了显示高超的挖掘机驾驶技巧,比赛的分数就是在场地上转弯的次数,就是图中的1/4圆形标注的。比如1号图是12次,2号图是5次。
输入
一行:n (场地被划分成了n*n个格子 ,)
第2~n+1行:挖掘机的路线 (路线为从1 –>2->3…->n*n);
输出
一个整数,表示比赛的分数
样例输入
3
1 2 3
8 7 4
9 6 5
样例输出
5
思路
这题是十分简单的了,直接用个递归传输一下坐标和上一步的方向,判断一下,下一步与上一步方向是否一致,不一致结果就加一,直到走到位置上的数值就可以了。
核心代码void ss(int x,int y,int last)
{
if(a[x][y]==n*n)return;
if(a[x+1][y]==a[x][y]+1)//右
if(last==4||last==0)
ss(x+1,y,4);
else
{
s++;
ss(x+1,y,4);
}
else if(a[x][y+1]==a[x][y]+1)//下
if(last==2||last==0)
ss(x,y+1,2);
else
{
s++;
ss(x,y+1,2);
}
else if(a[x-1][y]==a[x][y]+1)//左
if(last==3||last==0)
ss(x-1,y,3);
else
{
s++;
ss(x-1,y,3);
}
else if(a[x][y-1]==a[x][y]+1)//上
if(last==1||last==0)
ss(x,y-1,1);
else
{
s++;
ss(x,y-1,1);
}
}
第二题
1366. 拆除桥墩(remove)
(File IO): input:remove.in output:remove.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet
题目描述
河的左岸到右岸之间有一座年久失修、已经废弃的大桥,有 N 个桥墩,影响船只通行。现在要拆除部分桥墩,使得通航能力最大,通航能力由最窄的地方决定的,这个地方有可能是岸与桥墩之间,也可以是桥墩之间。工程预算有限,只能拆除 M 个桥墩。如何安排工程,才能使得通航能力尽可能的大。
输入
第一行包含三个整数 L,N,M,分别表示左岸到右岸的距离、桥墩数和需要拆除的桥墩数。
接下来 N 行,每行一个整数,第 i 行的整数 Di(0 < Di < L)表示第 i 桥墩与左岸的距离。这些桥墩按与左岸距离从小到大的顺序给出。
输出
一个整数,为拆除了 M 个桥墩之后,最窄的地方最大值。
样例输入
24 4 2
2
11
17
21
样例输出
6
思路
这一题考试时就想到了要用二分查找,但在判断是否成立的时候少了一条nxt<=n,这条语句,结果只得了50分。
这题先用二分查找出可能存在的间距,在判断一下是否能成立,如果成立,把左边的坐标赋值加大到左右坐标的mid值+1,否则右边坐标赋值为加大到左右坐标的mid值-1。
主要就是判断部分程序,这题也是比较简单的。
bool ss(int t)//需要判断的最下距离
{
int now=0,nxt,ans=0;//now是指某一段的开始值
//nxt是后面while循环判断的结束位置
//ans是需要锯掉的木桩数
while(now<=n)
{
nxt=now+1;
while(a[nxt]-a[now]<t&&nxt<=n)
{
nxt++;
ans++;
}
now=nxt;//把下一次开头更换为这一次结尾
}
return ans<=m
//如果ans小于最大能锯的木桩,返回true,否则返回false
}
第三题
1367. 扑克游戏(poker)
(File IO): input:poker.in output:poker.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet
题目描述
有一种别样“小猫钓鱼”扑克游戏。有 N 张牌,每张牌都有一个花色和点数。游戏的规则:扑克接龙时,若前面有同样花色的牌,你可以将这两张牌连同之间的牌都取走,得到的分值为取走牌点数之和。这里说的是可以,不是必须。给定扑克接龙的顺序,求最多的得分。
输入
第一行一个整数 N。
第二行 N 个整数,依次表示 1~N 张牌的花色。
第三行 N 个整数,依次表示 1~N 张牌的点数。
输出
一个整数,为游戏可以得到最大得分。
样例输入
7
1 2 1 2 3 2 3
1 4 3 4 3 4 5
样例输出
23
数据范围限制
1<=n<=3000
这一题是一道前缀合加DP。
先把输入时存点数的数组存前缀合。
f[i]表示前i张扑克牌可以得到的最大的分。
接下来枚举1~n,将f[i]的初始值赋值为f[i-1]。
再枚举1~(i-1)如果前面牌第j张牌的花色和第i张牌的花色相同,那么就把f[i]的值更新为f[i]与f[j-1]加上第i张牌到第j张牌点数的和。
最后输出f[n]
f[i]=f[i-1];//赋初始值不能忘
for(int j=1;j<i;j++)
if(a[i]==a[j])//同花色
f[i]=max(f[i],f[j-1]+b[i]-b[j-1]);
//动态转移方程