国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Hrbust 1255/CSU 1070 Knight Match Play【思維+Bfs預處理+Kmp】好題~

2019-11-06 06:21:10
字體:
來源:轉載
供稿:網友

Knight Match Play
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 31(5 users)Total Accepted: 5(4 users)Rating: Special Judge: No
Description
There are two knight teams, they have N and M knights respectively. The knights are numbered from 1 to N and 1 to M in their own team. They are trapped in a W*H grid puzzle. The puzzle only has four exituses which are the four corners of the puzzle. Only the directions up,down,left,right could the knight move to and the time move from one grid to the adjacent is fixed. They can form a "fight partner" if two knights sufficing the following conditions:1, The two knights come from different teams.2, Both of them can arrive to one of the exituses.3, The least time need to arrive to one of the exituses is same.

So how many "fight partners" they can form?

1255

For this action, the leader gives the follow directives:1, Each team renumbering the knights with their least time need to use to get out of the puzzle. So the one who use the least time will get the ID 1 and the one use the most time will get the ID N or M. If some of them use the same time, then whose original ID is lower, who will get a lower ID.2, The chosen knights from the same team should have the continuous ID.3, Form "fight partners" according to the IDs one by one. That is to say the one has the lowest ID should form with the one has the lowest ID in another team, and so on.

Input
There are several test cases. The input of every test case are described as below.First line, there are four integers N,M,W,H. (0<n,m<300, 10<w,h<50). Then there are H lines, each line with W characters indicate for the puzzle. A character of '.' indicate the grid is empty, every empty grid could contain infinitely of knights. A character of '#' means the grid has a barrier and none knight can step into it. The four corners are empty. Then there N+M lines, each line with a pair of integers (x,y)(0<=x<h,0<=y<w) originally. The input will finish with the end of file
Output

An integer indicate for the maximal number of "fight partner" they can form.

Sample Input

4 3 7 6.#...#...#.............#........##..##....1 34 22 21 53 54 33 0

Sample Output

3

Source
Hunan University 2011 the 7th PRogramming Contest
Recommend
萬祥

題目大意:

給你一個H*W大小的一個迷宮,其中#表示不能走,“.”表示可以走,

現在迷宮的出口在四個角落(左上.左下.右上.右下);

我們規定一共有兩活人,一伙N個,一伙M個,初始的時候編號按照輸入順序編號.

現在規定合作伙伴:

①合作伙伴是兩個人,并且來自不同的陣營。

②兩個人到達其最近的出口耗時相同。

然后我們需要將兩個陣營的騎士重新編號。

重新編號的規則按照:按照逃出迷宮從小到大的時間排序,然后按照這個順序從新編號。對于時間相同的,按照原序列優先級編號。

然后得到兩個重新編號的數組A.B.讓你在任意一個數組中取任意一段連續子序列,讓其是另外一個數組的子串,求這個合法子段的最長長度。

思路:

1、根據手動測試數據范圍已知,n,m不大于300.W.H不大于500.

2、題目很復雜,我們首先簡化問題,其實就是讓你①先求出每個人逃出迷宮的時間,然后按照時間點從小到大排序得到兩個數組,②然后求一個數組任意取一段連續子段是另外一個數組的子串即可,我們需要求一個最大長度。

3、那么我們首先處理前部分任務:

我們對于一個圖的遍歷的時間復雜度是O(nm)如果我們對于每一個騎士進行Bfs,肯定是超時的,那么我們Bfs四個起點,維護一個數組step【i】【j】.表示從任意起點到(i,j)這個位子的最短時間消耗,反過去考慮,step【i】【j】其實就是從(i,j)這一點,到任意出口的最小時間花費。

那么對于每個騎士來講,其逃出的時間,就是step【x】【y】;

這部分時間復雜度:O(nm);

4、然后我們處理后置任務。

①對于我們處理出來的兩個數組,按照時間從小到大先排個序,模擬題目要求。

②考慮到KMP匹配的特性,我們只需O(n)枚舉A.B數組中較小的那個序列的起點,去匹配另一個序列即可,過程維護一個最大匹配長度值。

③這里有一個trick.輸入數據不保證一個點一定能夠走到出口。所以從小到大排序結束之后,要重新界定一下數組的大小(就是要把不能走到終點的那些去除掉)。

④過程維護一個最大值即可。

時間復雜度O(min(lena,lenb)*(lena+lenb));

5、總體來說題目比較綜合,而且坑點十足,尼瑪對拍數據都調了很久才過,給這個題一個好評吧,估計也沒幾個人能做這個題了(- -);

Ac代碼:

#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;struct node{    int x,y;}now,nex;char mp[505][505];int step[505][505];int numa[505];int numb[505];int fx[4]={0,0,1,-1};int fy[4]={1,-1,0,0};int a[500];int b[500];int naxt[2500];int conta,contb,n,m;int lena,lenb;int Bfs(){    queue<node >s;    for(int i=0;i<n;i++)    {        for(int j=0;j<m;j++)        {            step[i][j]=0x3f3f3f3f;            if((i==0&&j==0)||(i==n-1&&j==m-1)||(i==n-1&&j==0)||(i==0&&j==m-1))            {                now.x=i;                now.y=j;                step[i][j]=0;                s.push(now);            }        }    }    while(!s.empty())    {        now=s.front();        s.pop();        for(int i=0;i<4;i++)        {            nex.x=now.x+fx[i];            nex.y=now.y+fy[i];            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&mp[nex.x][nex.y]!='#')            {                if(step[nex.x][nex.y]>step[now.x][now.y]+1)                {                    step[nex.x][nex.y]=step[now.x][now.y]+1;                    s.push(nex);                }            }        }    }    return 0;}void set_naxt()//子串的naxt數組{    int i=0,j=-1;    naxt[0]=-1;    while(i<lenb)    {        if(j==-1||b[i]==b[j])        {            i++; j++;            naxt[i]=j;        }        else        j=naxt[j];    }}int KMP(){    int maxnlen=0;    int i=0,j=0;    set_naxt();    while(i<lena)    {        if(j==-1||a[i]==b[j])        {            i++;j++;            maxnlen=max(j,maxnlen);        }        else        {            maxnlen=max(j,maxnlen);            j=naxt[j];        }        if(j==lenb)        {            return lenb;        }    }    return maxnlen;}int main(){    while(~scanf("%d%d%d%d",&conta,&contb,&m,&n))    {        for(int i=0;i<n;i++)scanf("%s",mp[i]);        Bfs();        for(int i=0;i<conta;i++)        {            int x,y;            scanf("%d%d",&x,&y);            numa[i]=step[x][y];        }        for(int i=0;i<contb;i++)        {            int x,y;            scanf("%d%d",&x,&y);            numb[i]=step[x][y];        }        sort(numa,numa+conta);        sort(numb,numb+contb);        for(int i=0;i<conta;i++)        {            if(numa[i]==0x3f3f3f3f)            {                conta=i;                break;            }        }        for(int i=0;i<contb;i++)        {            if(numb[i]==0x3f3f3f3f)            {                contb=i;                break;            }        }        int output=0;        if(conta<contb)        {            lena=contb;            for(int i=0;i<contb;i++)            {                a[i]=numb[i];            }            for(int i=0;i<conta;i++)            {                lenb=0;                for(int j=i;j<conta;j++)                {                    b[lenb++]=numa[j];                }                output=max(KMP(),output);            }        }        else        {            lena=conta;            for(int i=0;i<conta;i++)            {                a[i]=numa[i];            }            for(int i=0;i<contb;i++)            {                lenb=0;                for(int j=i;j<contb;j++)                {                    b[lenb++]=numb[j];                }                output=max(KMP(),output);            }        }        printf("%d/n",output);    }}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 大同市| 禹州市| 蒙城县| 隆德县| 道孚县| 柳州市| 东宁县| 腾冲县| 尤溪县| 海安县| 富锦市| 红河县| 浮山县| 昔阳县| 罗城| 台湾省| 酒泉市| 吴川市| 盖州市| 类乌齐县| 衡水市| 阳东县| 东海县| 江永县| 班戈县| 高清| 化德县| 博湖县| 徐水县| 和林格尔县| 兴安县| 康定县| 牙克石市| 玉龙| 元朗区| 桃园县| 奉节县| 枣强县| 康保县| 兴仁县| 鄂州市|