[Simulated game] to improve the group 19.8.9 A test Jizhong

Task.1 go plaid

Title effect: C and F can be regarded as a \ (N \ times M \) of the room matrix, each element in the matrix may be:

  1. obstacle:"#"

  2. The starting point C or F: "C" or "F"

  3. Empty areas:. ""

C carries a gun transmission, each C can be:

  1. A unit of time spent moving to an adjacent empty area

  2. Do not spend time on the wall of one of the vertical and horizontal directions of emission Portal (Portal can only exist two, if there is already two and then launch a door that first appeared disappear, a location can not exist two fan portal)

  3. It takes a unit of time into the mobile portal to another grid in front of the transfer gate on the adjacent wall.

C F to find the minimum time.

Data range: \ (1 \ Leq N, M \ Leq 500 \) , to ensure that the map is the outermost barrier.

https://store.steampowered.com/app/400/Portal/

We think up burst search? You can live it?You can get good results 85pts's? ? ?

Correct operation is this: When you are in a position, you can launch two portals to the four directions, that will be able to go to the nearest wall into the portal to another in front of a wall.

Approach is very simple: bfs or shortest path algorithm, consider the above it.

Code:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<utility>
using namespace std;

template<class T>void read(T &x){
    x=0; char c=getchar();
    while(c<'0'||'9'<c)c=getchar();
    while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
}
typedef pair<int,int> pr;
const int N=505;

int n,m,s,t;
char mp[N][N];
vector<pr>e[N*N];
int num[N][N],L[N][N],R[N][N],U[N][N],D[N][N];
int dis[N*N];
priority_queue<pr>q;
bool vis[N*N];
int dx[5]={0,0,1,-1};
int dy[5]={1,-1,0,0};

void add(int x,int y,int w){e[x].push_back(pr(y,w));}
bool dijkstra(){
    memset(vis,0,sizeof(vis));
    memset(dis,0x7f,sizeof(dis));
    dis[s]=0; q.push(pr(0,s));
    pr now; int x,y,d;
    while(!q.empty()){
        now=q.top(); q.pop();
        x=now.second; if(vis[x])continue; vis[x]=1;
        for(int i=e[x].size()-1;~i;i--){
            y=e[x][i].first; d=e[x][i].second;
            if(dis[y]>dis[x]+d){
                dis[y]=dis[x]+d;
                if(!vis[y])q.push(pr(-dis[y],y));
            }
        }
    }
    return dis[t]!=dis[0];
}
int main(){
    freopen("cell.in","r",stdin);
    freopen("cell.out","w",stdout);
    read(n); read(m); int cnt=0;
    for(int i=1;i<=n;i++){
        scanf("%s",mp[i]+1);
        for(int j=1;j<=m;j++){
            if(mp[i][j]=='#'){L[i][j]=R[i][j]=U[i][j]=D[i][j]=-1; continue;}
            num[i][j]=++cnt;
            if(mp[i][j]=='C') s=num[i][j];
            if(mp[i][j]=='F') t=num[i][j];
            L[i][j]=L[i][j-1]+1; U[i][j]=U[i-1][j]+1;
        }
    }
    for(int i=n;i;i--) for(int j=m;j;j--) if(mp[i][j]!='#'){R[i][j]=R[i][j+1]+1; D[i][j]=D[i+1][j]+1;}
    int nx,ny,d;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) if(mp[i][j]!='#'){
            for(int k=0;k<4;k++){
                nx=i+dx[k]; ny=j+dy[k];
                if(mp[nx][ny]=='#')continue;
                add(num[i][j],num[nx][ny],1);
            }
            d=min(min(L[i][j],R[i][j]),min(U[i][j],D[i][j]))+1;
            add(num[i][j],num[i][j-L[i][j]],d);
            add(num[i][j],num[i][j+R[i][j]],d);
            add(num[i][j],num[i-U[i][j]][j],d);
            add(num[i][j],num[i+D[i][j]][j],d);
        }
    }
    if(dijkstra()) printf("%d\n",dis[t]);
    else puts("wtf");
    return 0;
}

Task.2 twisting tree

Subject to the effect: There is a \ (key \) as key \ (val \) is the weight \ (n \) points a binary search tree, the definition of a node \ (sum \) value of its sub-tree in \ (val \) and. Tell you \ (n \) nodes \ (key \) value and \ (val \) values, seeking to satisfy any one side of the tree two endpoints \ (key \) value is the greatest common divisor is not \ (1 \) when the tree of all nodes \ (sum \) and how much is maximum value.

范围数据: \ (1 \ leq N \ leq 300,1 \ leq key_i \ leq 10 ^ 18,1 \ leq val_i \ leq 10 ^ 6 \)

Ordered a binary search tree traversal is the result of all the sort keys. After trying to sort \ (n-\) elements are combined, may be used ideas similar interval DP is defined state \ (f_ {i, j, k} \) representing the interval \ ([i, j] \ ) are combined into a trees subtree root is \ (K \) maximum answer, is similar to the transfer section DP, the complexity of the \ (O (n-^. 4) \) .

This idea is optimized: the interval \ ([i, j] \ ) to \ (K \) for the root situation must ultimately be made \ ([i, k-1 ] \) and \ ([k + 1, j ] \) get. So we tried to improve the above-described third dimension about DP, defined \ (f_ {i, j, 0/1} \) representing the interval \ ([i, j] \ ) to \ (i-1 \) or \ ( j + 1 \) is the root of the answer, transfer interval DP is still similar to the enumeration root \ (K \) , the complexity of the \ (O (N ^. 3) \) .

Code:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<utility>
using namespace std;
template<class T>void read(T &x){
    x=0; char c=getchar();
    while(c<'0'||'9'<c)c=getchar();
    while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
}
typedef long long ll;
typedef pair<ll,ll> pr;
const int N=305;
#define key first
#define val second
int n;
pr a[N];
ll sum[N],f[N][N][2],ans;
bool e[N][N];
void cmax(ll &x,ll y){if(x<y)x=y;}
ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
int main(){
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    read(n);
    for(int i=1;i<=n;i++){read(a[i].key); read(a[i].val);}
    sort(a+1,a+n+1);
    if(a[1].key==1){puts("-1"); return 0;}
    memset(f,-0x3f,sizeof(f));
    for(int i=1;i<=n;i++){
        sum[i]=sum[i-1]+a[i].val;
        for(int j=i+1;j<=n;j++)
            e[i][j]=(gcd(a[i].key,a[j].key)!=1);
        if(e[i-1][i]) f[i][i][0]=a[i].val;
        if(e[i][i+1]) f[i][i][1]=a[i].val;
    }
    for(int len=2;len<=n;len++)
        for(int i=1,j=i+len-1;j<=n;i++,j++){
            ll cost=sum[j]-sum[i-1];
            for(int k=i;k<=j;k++){
                ll add=(i<k)*f[i][k-1][1]+(k<j)*f[k+1][j][0]+cost;
                if(e[i-1][k]) cmax(f[i][j][0],add);
                if(e[k][j+1]) cmax(f[i][j][1],add);
                if(len==n) cmax(ans,add);
            }
        }
    printf("%lld\n",ans);
    return 0;
}

Task.3 rotating field

Title effect: a defined value is arranged arrangement (p_i = i \) \ number of such fixed point. Now interval and to select a \ ([L, R] \ ) reversing, flipping up the rear fixing points required.

Data range: \ (. 1 \ Leq N \ ^. 5 Leq 10 \)

Have such a nature: the position \ (I \) numbers on \ (X \) on \ (\ frac {(i + x)} {2} \) folded generated \ (1 \) contribution, and number on a location it will have contributed symmetry points are fixed. Consider again the last flip answer section looks like: about the interval endpoint has at least one point of symmetry (range midpoint) will have contributed flip, or if two endpoints chose this will not be the answer becomes excellent.

According to the above analysis, we thought of a greedy approach: the point in the same point of symmetry do together, reaching the small radius section enumerated, and the use of the prefix differential inverting interval other than the answer, the complexity of the \ (O (N ^ 2) \) . Not good enough, we found a lot of extra cases when enumerating radius, to get rid of these cases, each enumeration range from near to far end, no contribution to skip the point of flip, the same calculation methods and the answer above. Such that each location is only considered once complexity \ (O (N) \) .

Code:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;

template<class T>void read(T &x){
    x=0; char c=getchar();
    while(c<'0'||'9'<c)c=getchar();
    while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
}
typedef pair<int,int> pr;
void cmax(int &x,int y){if(x<y)x=y;}
void cmin(int &x,int y){if(x>y)x=y;}
const int N=100050;
int n,a[N],pre[N],ans;
vector<int>q[N<<1];
int main(){
    freopen("rotate.in","r",stdin);
    freopen("rotate.out","w",stdout);
    read(n);
    for(int i=1;i<=n;i++){
        read(a[i]); pre[i]=pre[i-1]+(a[i]==i);
        if(a[i]>i) q[a[i]+i].push_back(a[i]);
        else q[a[i]+i].push_back(i);
    }
    int L,R;
    for(int i=(n<<1);i>1;i--){
        sort(q[i].begin(),q[i].end());
        for(int j=0;j<q[i].size();j++){
            R=q[i][j]; L=i-R;
            cmax(ans,pre[L-1]+pre[n]-pre[R]+j+1);
        }
    }
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/opethrax/p/11333979.html