2019秦皇岛CCPC现场赛E,J题

MUV LUV EXTRA

Time Limit: 2000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 555    Accepted Submission(s): 168

Problem Description

One day, Kagami Sumika is stuck in a math problem aiming at calculating the length of a line segment with given statements and constraints. Since Sumika has no idea about it, she takes out a ruler and starts to measure the length. Unfortunately, the answer is an infinite decimal and she only got the first some digits of the answer from the ruler.
Sumika guesses that the answer is a rational number, which means that there exists two integers p, q that the answer equals qp. In this situation, the answer can be expressed as an infinte repeated decimal. For example, 12 = 0.500 ... , 13 = 0.333 .... , 910= 0.8999 ... ,3635= 1.0285714285714 ... .Sumika wants to guess the original number from the digits she got. Note that a number may has more than one way to be expressed such as 1.000 ... = 0.999 ... . Sumika won’t transform the digits she got to another form when guessing the original number.
Furthermore, Sumika relizes that for a repeating part, either too long or the appeared length too short will make the result unreliable. For example, if the decimal she measured is 1.0285714285714, it is obviously unreliable that the repeating part is “0285714285714”, since it is too long, or “428571”, since the appeared length is too short, which equals 7, the length of “4285714”. In this case, the best guess is “285714”, whose length is 6 and the appeared length is 12. So formally, she defines the reliability value of a repeating part, whose length is l and the appeared length is p, as the following formula:

a * p - b * l
Where a and b are given parameters.
Last but not least, you can ignore the integer parts of the decimal. It is just for restoring the scene. And the repeating part you guess should be completely repeated at least once and is still repeating at the end currently.
Please help Sumika determine the maximum reliability value among all repeating parts.

Input

The first line contains two positive integers a, b (1 ≤ a, b ≤ 109), denoting the parameters.
The next line contains a string s (1 ≤ |s| ≤ 107) in decimal form, denoting the first some digits of the accurate result.
It is guaranteed that there is exactly one decimal point in s and s is a legal non-negative decimal without leading "-"(the minus sign).

Output

Output a single line containing an integer, denoting the maximum reliability value.

Sample Input

5 3

1.1020 

2 1

12.1212

Sample Output

9

6

题意:找出最可靠的循环节,可靠值计算a*(循环体在字符串里出现的长度)-b*(循环体长度)。

题解:将字符串倒过来,枚举每个前缀串的i-next[i]即是循环体长度。

#include 
#define ll long long
#define inf 1e15
using namespace std;
char x[10000010];
char tmp[10000010];

void kmp_pre(char x[],int m,int nexts[])
{
    int i,j;
    j=nexts[0]=-1;
    i=0;
    while(i=0; i--)
        {
            if(tmp[i]=='.') break;
            x[j]=tmp[i];
            j++;
        }
        kmp_pre(x,j,nexts);
        ll ans=a*1ll-b*1ll;
        for(int i=1; i<=j; i++)
        {
            ll t;
            t=a*1ll*i-b*1ll*(i-nexts[i]);
            ans=max(ans,t);
        }
        printf("%lld\n",ans);
    }

    return 0;
}

Escape

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 98    Accepted Submission(s): 45

Problem Description

Given a maze of size n×m. The rows are numbered 1, 2, · · · , n from top to bottom while the columns are numbered 1, 2, · · · , m from left to right, which means that (1, 1) is the top-left corner and that (n, m) is the bottom-right corner. And for each cell of size 1 × 1, it is either blank or blocked.
There are a robots above the maze. For i-th robot, it is initially positioned exactly above the cell (1, pi), which can be described as (0, pi). And the initial moving direction of the robots are all downward, which can be written as (1, 0) in the vector form.
Also, there are b exits below the maze. For i-th exit, it is positioned exactly below the cell (n, ei), which can be described as (n + 1, ei).
Now, you want to let the robots escape from the maze by reaching one of the exits. However, the robots are only able to go straight along their moving directions and can’t make a turn. So you should set some turning devices on some blank cells in the maze to help the robots make turns.
There are 4 types of turning devices:

  • “NE-devices” : make the robots coming from above go rightward, and make the robots coming from right go upward. Coming from left or below is illegal.
  • “NW-devices” : make the robots coming from above go leftward, and make the robots coming from left go upward. Coming from right or below is illegal.
  • “SE-devices” : make the robots coming from below go rightward, and make the robots coming from right go downward. Coming from left or above is illegal.
  • “SW-devices” : make the robots coming from below go leftward, and make the robots coming from left go downward. Coming from right or above is illegal.
  • For each cell, the number of turning devices on it can not exceed 1. And collisions between the robots are ignored, which allows multiple robots to visit one same cell even at the same time.
    You want to know if there exists some schemes to set turning devices so that all the a robots can reach one of the b exits after making a finite number of moves without passing a blocked cell or passing a turning device illegally or going out of boundary(except the initial position and the exit).
    If the answer is yes, print “Yes” in a single line, or print “No” if the answer is no.

Input

The first line contains one positive integer T (1 ≤ T ≤ 10), denoting the number of test cases.
For each test case:
The first line contains four positive integers n, m, a, b (1 ≤ n, m ≤ 100, 1 ≤ a, b ≤ m), denoting the number of rows and the number of columns in the maze, the number of robots and the number of exits respectively.
Next n lines each contains a string of length m containing only “0” or “1”, denoting the initial maze, where cell (i, j) is blank if the j-th character in i-th string is “0”, while cell (i, j) is blocked if the j-th character in i-th string is “1”.
The next line contains a integers pi (1 ≤ pi ≤ m), denoting the initial positions (0, pi) of the robots.
The next line contains b integers ei (1 ≤ ei ≤ m), denoting the positions (n + 1, ei) of the exits.
It is guaranteed that all pis are pairwise distinct and that all eis are also pairwise distinct.

Output

Output T lines each contains a string “Yes” or “No”, denoting the answer to corresponding test case.

Sample Input

2

3 4 2 2

0000

0011

0000

1 4

2 4

3 4 2 2

0000

0011

0000

3 4

2 4

Sample Output

Yes

No

Hint

题意:给出一个n*m的迷宫,1代表障碍格子,有a个机器人,b个出口,机器人的起始位置(0,p_i),出口位置(n+1,e_i)。你可以在某些格子放置机关使得机器人按照机关的规则转弯(机器人只会走直线),问是否可以存在方案使得所有机器人都能走出迷宫。

做法:所有机器人的起点都不一样,也就是每一个两个机器人的路径是完全重叠的,按照机关的规则可以知道,如果存在重叠部分即是路线不合法,而最大流的割边的过程正好排除了找到重叠路线的做法。我们只需要在那些不是障碍的格子与周围的格子连一条边,跑一下最大流即可。

#include 
#define ll long long
#define inf 1e15
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
struct edge{int to,cap,rev;};
vector  G[20010];//邻接图的表示
int level[20010];//顶点到源点的距离标号
int iter[20010];//当前弧,在其之前的边就已经没有用了
void add_edge(int from,int to,int cap)
{
    G[from].push_back((edge){to,cap,G[to].size()});
    G[to].push_back((edge){from,0,G[from].size()-1});
}
//通过BFS计算从源点出发的距离的标号
void bfs(int s)
{
    memset(level,-1,sizeof(level));
    //fill(level,level+400,-1);
    queue que;
    level[s]=0;
    que.push(s);
    while(!que.empty()){
        int v =que.front();que.pop();
        for(int i=0;i0&&level[e.to]<0){
                level[e.to]=level[v]+1;
                que.push(e.to);
            }
        }
    }
}

int dfs(int v,int t,int f)
{
    if(v==t||f==0) return f;
    for(int &i=iter[v];i0&&level[v]0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

int dinic(int s,int t)
{
    int flow=0;
    for(;;){
        bfs(s);
        if(level[t]<0) return flow;
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,INF))>0){
            flow+=f;
        }
    }
    return flow;
}
char g[110][110];
int p[110][110];
int dir[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
int start[110];
int endd[110];
int main(){
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int a,b,n,m;
        scanf("%d %d %d %d",&n,&m,&a,&b);
        int s=0;int t=11000;
        for(int i=0;i<=t;i++)
        {
            G[i].clear();
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%s",g[i]+1);
        }
        for(int i=1;i<=a;i++)
        {
            scanf("%d",&start[i]);
        }
        for(int j=1;j<=b;j++)
        {
            scanf("%d",&endd[j]);
        }
        int po=1;
        for(int i=0;i<=n+1;i++)
        {
            for(int j=1;j<=m;j++)
            {
                p[i][j]=po;
                po++;
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(g[i][j]!='1')
                {
                    for(int k=0;k<4;k++)
                    {
                        int tx=dir[k][0]+i;
                        int ty=dir[k][1]+j;
                        if(tx<=0||tx>n||ty<=0||ty>m||g[tx][ty]=='1') continue;
                        add_edge(p[i][j],p[tx][ty],1);
                    }
                }
            }
        }
        for(int i=1;i<=m;i++)
        {
            if(g[1][i]=='1') continue;
            add_edge(p[0][i],p[1][i],1);
        }
        for(int i=1;i<=m;i++)
        {
            if(g[n][i]=='1') continue;
            add_edge(p[n][i],p[n+1][i],1);
        }
        for(int i=1;i<=a;i++)
        {
            add_edge(s,p[0][start[i]],1);
        }
        for(int j=1;j<=b;j++)
        {
            add_edge(p[n+1][endd[j]],t,INF);
        }
        if(dinic(s,t)==a)
        {
            printf("Yes\n");
        }
        else printf("No\n");
    }
    return 0;
}

 

你可能感兴趣的:(ACM)