5.20考试整理

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 <queue>
#include <cmath>
#define INF 0x7fffffff

using namespace std;

const int M = 55;
const int N = 1e4 + 5;
int n,m,cnt;//<=50
int dx[5] = {0,0, 0,1,-1},
    dy[5] = {0,1,-1,0, 0};//right left down up
int jz[M][M];
bool v[M][M];
char cc[M];
int sx,sy,ex,ey;

struct AA{
    int x,y,step,f;
}zz[N],cv;
queue<AA>QwQ;

inline int read()
{
    int 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;
}

void bfs1()
{
    int xx,yy;
    while(!QwQ.empty())
    {
        cv=QwQ.front();
        int x=cv.x,y=cv.y;
        QwQ.pop();    
        for(int i=1;i<=4;i++)
        {
            xx=x+dx[i];
            yy=y+dy[i];
            if(xx>n || xx<1 || yy>m || yy<1 || v[xx][yy]) continue;
            if((xx==ex && yy==ey) || jz[xx][yy]!=INF) continue;
            jz[xx][yy]=jz[x][y]+1;
            cv.x=xx,cv.y=yy;
            QwQ.push(cv);
        }
    }
}

void bfs2()
{
    while(!QwQ.empty()) QwQ.pop();//qing kong
//    for(int i=1;i<=cnt;i++)
//        QwQ.push(zz[i]);
    zz[0].x=sx,zz[0].y=sy;
    QwQ.push(zz[0]);
    int xx,yy;
    while(!QwQ.empty())
    {
        cv=QwQ.front();
        int x=cv.x,y=cv.y,step=cv.step;
        QwQ.pop();    
        for(int i=1;i<=4;i++)
        {
            xx=x+dx[i];
            yy=y+dy[i];
            if(xx>n || xx<1 || yy>m || yy<1 || v[xx][yy] || step+1>=jz[xx][yy]) continue;
            v[xx][yy]=true;
            if(xx==ex && yy==ey)
            {
                printf("%d",step+1);
                return;
            }
            cv.x=xx,cv.y=yy,cv.step=step+1;
            QwQ.push(cv);
        }
    }
    printf("ORZ hzwer!!!");
}

int main()
{
//    freopen("sliker.in","r",stdin);
//    freopen("sliker.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            jz[i][j]=INF;//chu shi hua
    for(int i=1;i<=n;i++)
    {
        scanf("%s",cc);
        for(int j=1;j<=m;j++)
        {
            if(cc[j-1] == 'D') {ex=i;ey=j;}
            if(cc[j-1] == 'S') {sx=i;sy=j;}
            if(cc[j-1] == 'X') v[i][j]=1;
            if(cc[j-1] == '*') 
            {
                zz[++cnt].x=i;
                zz[cnt].y=j;
                QwQ.push(zz[cnt]);
                jz[i][j]=0;
            }
        }
    }
    bfs1();
    bfs2();
    return 0;
}
/*
3 6
D...*.
.X.X..
....S.

6

3 3
D.*
...
.S.

3

3 3
D.*
...
..S

ORZ hzwer!!!
*/
STL版
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#define inf 0x7fffffff

using namespace std;

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x*=10;x+=ch-'0';ch=getchar();}
    return x*f;
}

int n,m,bx,by,ex,ey;
int t,w;
int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1};
char ch[55];
bool mp[55][55];
int tim[55][55];

struct data{int x,y,step,f;}q[10005];

void bfs1()
{
     while(t!=w)
     {
         int x=q[t].x,y=q[t].y;t++;
         for(int i=0;i<4;i++)
         {
             int nowx=x+xx[i],nowy=y+yy[i];
             if(nowx>n||nowy>m||nowx<1||nowy<1||mp[nowx][nowy])continue;
             if((nowx==ex&&nowy==ey)||tim[nowx][nowy]!=inf)continue;
             tim[nowx][nowy]=tim[x][y]+1;
             q[w].x=nowx;q[w].y=nowy;w++;
         }
     }
}

void bfs2()
{
     t=0,w=1;q[0].x=bx;q[0].y=by;
     while(t!=w)
     {
               
         int x=q[t].x,y=q[t].y,step=q[t].step;t++;
         for(int i=0;i<4;i++)
         {
             int nowx=x+xx[i],nowy=y+yy[i];
             if(nowx>n||nowy>m||nowx<1||nowy<1||mp[nowx][nowy]||step+1>=tim[nowx][nowy])
                 continue;
             mp[nowx][nowy]=1;
             if(nowx==ex&&nowy==ey){printf("%d",step+1);return;}
             q[w].x=nowx;q[w].y=nowy;q[w].step=step+1;w++;
         }
     }
     printf("ORZ hzwer!!!");
}

int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            tim[i][j]=inf;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch);
        for(int j=1;j<=m;j++)
        {
            if(ch[j-1]=='D'){ex=i;ey=j;}
            if(ch[j-1]=='S'){bx=i;by=j;}
            if(ch[j-1]=='X')mp[i][j]=1;
            if(ch[j-1]=='*'){q[w].x=i;q[w].y=j;tim[i][j]=0;w++;}
        }
    }
    bfs1();
    bfs2();
    return 0;
}
hzwer! 

某种数列问题  (jx.cpp/c/pas)

1000MS 256MB

众所周知,chenzeyu97有无数的妹子(阿掉!>_<),而且他还有很多恶趣味的问题,继上次纠结于一排妹子的排法以后,今天他有非(chi)常(bao)认(cheng)真(zhe)去研究一个奇怪的问题。有一堆他的妹子站成一排,然后对于每个妹子有一个美丽度,当然美丽度越大越好,chenzeyu97妹子很多,但是质量上不容乐观,经常出现很多美丽度为负数的妹子(喜闻乐见),chenzeyu97希望从一排妹子里找出3队连续的妹子,使她们的美丽度和最大。注意,一个妹子不能被编入多个队伍而且一定要拿出三队,不然czy会闲着没事做~。

简单滴说就是:

给定一个数列,从中找到3个无交集的连续子数列使其和最大。

【输入文件】

第一行一个数n,表示数列长度。

接下来有n行,每行一个数,第i行为第i个数。

【输出文件】

仅有一个数,表示最大和。

【样例输入】 jx.in

10

-1

2

3

-4

0

1

-6

-1

1

-2

【样例输出】 jx.out

7

【样例说明】

第一队妹子取2,3。

第二队妹子取0,1。

第三队妹子取1。

【数据范围】

请大家放心,虽然chenzeyu97妹子无数,但是这次他叫来的个数n是有限的。=v=

对于30%的数据,妹子数不大于200。

对于60%的数据,妹子数不大于2000。

对于100%的数据,妹子数1000000。

而且,由于chenzeyu97没有CCR那样的影响力,所以他的妹子选完的最大美丽度和不超过maxlongint。(注:CCR随便选就爆long long,因为他是把妹狂魔=V=)。

思路:

恶心的DP

代码酱=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[n][2][0],f[n][2][1]);
    cout<<ans;
    /*
    if(cnt<=2 || (mz[1]<0 && cnt==3) || (mz[n]<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.

posted @ 2017-05-22 17:34  夜雨声不烦  阅读(144)  评论(0编辑  收藏  举报