zoukankan      html  css  js  c++  java
  • 9.18

    9.18

    凄凄惨惨戚戚——60送走大家ak

    我想到的:
    报数m-1 必然是必败态,那么只要自己在[now+1,now+k]中有一个必胜态则必胜,全是必败态则必败
    没想到的:
    dp。。。设dp[i][j]表示第i只animal报到j数字的胜利状态 1(win)
    然后要倒着推,当前这个的状态由后面 [now+1,now+k]决定,我们只需记一个后缀数组
    用suf[now+1]-suf[min(m,k+1)+1]即使当前的答案

    (1) 没有硝烟的战争 ——dp

    #include <queue>
    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <utility>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N=5005;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    int n,m,k,a[N];
    int dp[N][N];//第i个报到j == 1(win) 
    int nxt[N],suf[N][N];//后缀的dp数组 
    
    int main() {
    	n=read();m=read();k=read();
    	for(int i=1;i<=n;i++) {
    		a[i]=read();
    		dp[i][m-1]=0;//lose 
    		nxt[i]=i+1;
    	}
    	nxt[n]=1;
    	for(int i=m-1;i;i--) {
    		for(int j=n;j>=1;j--) {
    			if(suf[nxt[j]][i+1]-suf[nxt[j]][min(i+k,m)+1]) dp[j][i]=1;
    			if(a[j]!=a[nxt[j]]) dp[j][i]^=1;
    			suf[j][i]=suf[j][i+1]+dp[j][i];
    		}
    	}
    	for(int i=1;i<n;i++)
    		printf("%d ",(suf[i][1]-suf[i][1+k])?a[i]:a[i]^1);//[1,k]有一个必胜态则自己win 
    	printf("%d
    ",(suf[n][1]-suf[n][1+k])?a[n]:a[n]^1);
    	return 0;
    }
    
    
    

    (2)秘密通道 ——最短路

    呃呃呃,60的原因。。。忘了可以在这开一枪跑到墙边再穿越

    正解就是连边最短路,第一种就是每一个格子向他周围四个方向连一条长度 为 1 的边。 第二种就是每一个格子向他上下左右的第一堵墙连一 条长度为格子与最近的墙距离的边。

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <utility>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N=505;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    int n,m;
    char mp[N][N];
    struct node{
    	int x,y,d;
    	node(){}
    	node(int x_,int y_,int d_):x(x_),y(y_),d(d_){}
    	bool operator < (const node &a) const {
    		return d>a.d;
    	} 
    };
    int stx,sty;
    int ex,ey;
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    bool vis[N][N];
    int dis[N][N];
    priority_queue<node>q;
    int main() {
    	n=read();m=read();
    	for(int i=1;i<=n;i++)	
    		scanf("%s",mp[i]+1);
    	memset(dis,0x3f,sizeof(dis));
    	for(int i=1;i<=n;i++)	
    		for(int j=1;j<=m;j++) {
    			if(mp[i][j]=='C') 
    				stx=i,sty=j;
    			else if(mp[i][j]=='F') 	
    				ex=i,ey=j;
    		}
    	q.push(node(stx,sty,0));
    	dis[stx][sty]=0;
    	while(q.size()) {
    		int x=q.top().x,y=q.top().y;q.pop();
    		if(vis[x][y]) continue;
    		vis[x][y]=1;
    		
    		int xx,yy,lx=x,rx=x,ly=y,ry=y;
    		int near=0x3f3f3f3f;
    		xx=x;
    		while(xx<n&&mp[xx+1][y]!='#') xx++;
    		if(mp[xx+1][y]=='#') near=min(near,xx-x),rx=xx;
    		xx=x;
    		while(xx>1&&mp[xx-1][y]!='#') xx--;
    		if(mp[xx-1][y]=='#') near=min(near,x-xx),lx=xx;
    		yy=y;
    		while(yy>1&&mp[x][yy-1]!='#') yy--;
    		if(mp[x][yy-1]=='#') near=min(near,y-yy),ly=yy;
    		yy=y;
    		while(yy<m&&mp[x][yy+1]!='#') yy++;
    		if(mp[x][yy+1]=='#') near=min(near,yy-y),ry=yy;
    		
    		near++;
    		if(dis[lx][y]>dis[x][y]+near) 
    			dis[lx][y]=dis[x][y]+near,q.push(node(lx,y,dis[lx][y]));
    		if(dis[rx][y]>dis[x][y]+near) 
    			dis[rx][y]=dis[x][y]+near,q.push(node(rx,y,dis[rx][y]));
    		if(dis[x][ly]>dis[x][y]+near) 
    			dis[x][ly]=dis[x][y]+near,q.push(node(x,ly,dis[x][ly]));
    		if(dis[x][ry]>dis[x][y]+near) 
    			dis[x][ry]=dis[x][y]+near,q.push(node(x,ry,dis[x][ry]));
    		
    		for(int i=0;i<4;i++) {
    			int xx=x+dx[i],yy=y+dy[i];
    			if(xx<1||yy<1||yy>m||xx>n||mp[xx][yy]=='#') continue;
    			if(dis[xx][yy]>dis[x][y]+1)
    				dis[xx][yy]=dis[x][y]+1,q.push(node(xx,yy,dis[xx][yy]));
    		}
    	}
    	if(dis[ex][ey]==dis[0][0]) puts("nemoguce");
    	else printf("%d
    ",dis[ex][ey]);
    	
    	return 0;
    }
    
    
    

    (3)城市猎人——按秩合并并查集

    见并查集

  • 相关阅读:
    WebApi 2:属性路由 [Route()],attribute routing
    WebApi:路由和Action选择
    1024 科学计数法(20 分)
    1023 组个最小数(20 分)
    1022 D进制的A+B(20 分)
    1021 个位数统计(15 分)
    1020 月饼(25 分)
    1019 数字黑洞(20 分)
    1018 锤子剪刀布(20 分)
    1017 A除以B(20 分)
  • 原文地址:https://www.cnblogs.com/ke-xin/p/13698890.html
Copyright © 2011-2022 走看看