您的位置:首页 > 其它

5.20考试整理

2017-05-22 17:34 113 查看

5.20考试整理

水灾(sliker.cpp/c/pas)

1000MS  64MB

大雨应经下了几天雨,却还是没有停的样子。土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没。

CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上有五种符号:“. * X D S”。其中“X”表示石头,水和人都不能从上面经过。“.”表示平原,CCY和洪水都可以经过。“*”表示洪水开始地方(可能有多个地方开始发生洪水)。“D”表示CCY的别墅。“S”表示CCY现在的位置。

CCY每分钟可以向相邻位置移动,而洪水将会在CCY移动之后把相邻的没有的土地淹没(从已淹没的土地)。

求CCY回到别墅的最少时间。如果聪哥回不了家,就很可能会被淹死,那么他就要膜拜黄金大神涨RP来呼叫直升飞机,所以输出“ORZ hzwer!!!”。

输入文件 sliker.in

输出文件 sliker.out

#1

Input

3 3

D.*

.S.

Output

3

#2

Input

3 3

D.*

..S

Output

ORZ hzwer!!!

#3

Input

3 6

D…*.

.X.X..

….S.

Output

6

谈心:

这道题就是一道广搜的题,但是我不会写..因为我觉得有好多个洪水一起开始发洪水没法写,但是是这样是错的,其实是能够写的,用队列啊!

在最后快要交卷的时候我想到了,但是因为没时间写了.所以没有写完.

而且我的数组开炸了...知道消息后我的内心是崩溃的!

明明在变量的后面敲上了注释范围,可是开数组的时候用M开的.qwq

思路:

首先bfs出每个点被淹没需要的时间,然后再bfs洪水:如果是洪水就让他入队,然后扩展状态,如果扩展到的状态"淹没了"这个人(不知道他是谁),就输出"ORZ hzwer!!!"

代码酱=u=

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>

using namespace std;

typedef long long LL;
const int M = 1e6 + 1;
LL n;
LL ans;
LL QwQ;
LL f[M][4][2];
//第几元素,第几队,该元素是否被选择
//f里面存的是到当前元素的最大解

inline LL read()//读入优化
{
LL x=0,f=1;
char ch=getchar();

while(ch>'9'||ch<'0')
{
if(ch='-') f=-1;
ch=getchar();
}

while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}

return x*f;
}

int main()
{
n=read();
//初始化f数组,因为要取最'大'值
memset(f,-127,sizeof(f));
for(LL i=1;i<=n;i++)
{
//读入下一个元素
QwQ=read();
/*
如果当前元素在第一队
①选上当前元素,所以需要判断一下前面的选不选
如果他是当前队的第一个元素,直接更新为本身的值就好啦
如果不是第一个元素,就用选上上一个元素的f值更新
在这两种情况中取出一个最大值更新
②不选当前元素,
所以当前的最大值就是用上一个状态来更新的
*/
f[i][0][1]=max(QwQ,f[i-1][0][1]+QwQ);
f[i][0][0]=max(f[i-1][0][0],f[i-1][0][1]);
/*
如果当前元素在第二队
①选上当前元素,所以需要判断一下前面的选不选
如果他是当前队的第一个元素,直接更新为本身的值加上上一队的最大值
如果不是第一个元素,就用选上上一个元素的f值加上当前元素的值更新
因为这是第二队!!!
然后在这两种情况中取出一个最大值更新
②不选当前元素,
所以当前的最大值就是用上一个状态来更新的
*/
f[i][1][1]=max(QwQ+f[i-1][0][0],QwQ+f[i-1][1][1]);
f[i][1][0]=max(f[i-1][1][0],f[i-1][1][1]);
//如果当前元素在第三队
//同
f[i][2][1]=max(QwQ+f[i-1][1][0],QwQ+f[i-1][2][1]);
f[i][2][0]=max(f[i-1][2][1],f[i-1][2][0]);
}
ans=max(f
[2][0],f
[2][1]);
cout<<ans;
/*
if(cnt<=2 || (mz[1]<0 && cnt==3) || (mz
<0 && cnt==3) || (mz[1]<0 && mz[i-1]<0 && cnt==4))
{
printf("%d",ans);
return 0;
}
*/
return 0;
}
DP

 

密码锁

1000MS 512MB

Input:  password.in

Output:  password.out

【题目描述】

hzwer有一把密码锁,由N个开关组成。一开始的时候,所有开关都是关上的。当且仅当开关x1,x2,x3,...xk为开,其他开关为关时,密码锁才会打开。

他可以进行M种的操作,每种操作有一个size[i],表示,假如他选择了第i种的操作的话,他可以任意选择连续的size[i]个格子,把它们全部取反。(注意,由于黄金大神非常的神,所以操作次数可以无限>_<)

本来这是一个无关紧要的问题,但是,黄金大神不小心他的钱丢进去了,没有的钱他哪里能逃过被chenzeyu97 NTR的命运?>_<  于是,他为了虐爆czy,也为了去泡更多的妹子,决定打开这把锁。但是他那么神的人根本不屑这种”水题”。于是,他找到了你。

你的任务很简单,求出最少需要多少步才能打开密码锁,或者如果无解的话,请输出-1。

【输入格式】

第1行,三个正整数N,K,M,如题目所述。

第2行,K个正整数,表示开关x1,x2,x3..xk必须为开,保证x两两不同。

第三行,M个正整数,表示size[i],size[]可能有重复元素。

【输出格式】

输出答案,无解输出-1。

【样例输入1】

10 8 2

1 2 3 5 6 7 8 9

3 5

【样例输出1】

2

【样例输入2】

3 2 1

1 2

3

【样例输出2】

-1

【数据规模】

对于50%的数据,1≤N≤20,1≤k≤5,1≤m≤3;

对于另外20%的数据,1≤N≤10000,1≤k≤5,1≤m≤30;

对于100%的数据,1≤N≤10000,1≤k≤10,1≤m≤100。

思路+代码:

超链接!!!

 

 

 

 

 

End.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: