• 2016-2017 ACM-ICPC East Central North America Regional Contest (ECNA 2016) (B, D, G, H)



    21.1.30 2016-2017 ACM-ICPC East Central North America Regional Contest (ECNA 2016)

    CF GYM 101196

    F 裸区间DP,gcd预处理下。I 网络流签到题。
    迷惑的一场,8题两个多小时做完就只能划水了。


    B. Foosball Dynasty √

    /*
    简单模拟 拿个queue 
    */
    #include <bits/stdc++.h>
    #define pc putchar
    #define gc() getchar()
    using namespace std;
    typedef long long LL;
    const int N=1e3+5;
    
    char s[N];
    string name[N];
    
    inline int read()
    {
    	int now=0,f=1; char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-48,c=gc());
    	return now*f;
    }
    
    int main()
    {
    	int n=read();
    	for(int i=1; i<=n; ++i) std::cin>>name[i];
    	scanf("%s",s+1); int m=strlen(s+1);
    
    	static std::queue<int> q;
    	for(int i=5; i<=n; ++i) q.push(i);
    	int now=0,wo=1,bo=2,wd=3,bd=4,mx=0,las=-1;//las=0:W las=1:B
    	for(int i=1; i<=m; ++i)
    		if(s[i]=='B')
    		{
    			if(las==1) ++now;
    			else now=1;
    			las=1, mx=std::max(mx,now);
    			std::swap(bo,bd);
    			q.push(wd), wd=wo, wo=q.front(), q.pop();
    		}
    		else
    		{
    			if(las==0) ++now;
    			else now=1;
    			las=0, mx=std::max(mx,now);
    			std::swap(wo,wd);
    			q.push(bd), bd=bo, bo=q.front(), q.pop();
    		}
    
    	int ans=mx; while(!q.empty()) q.pop();
    	for(int i=5; i<=n; ++i) q.push(i);
    	now=0,wo=1,bo=2,wd=3,bd=4,mx=0,las=-1;//las=0:W las=1:B
    	for(int i=1; i<=m; ++i)
    		if(s[i]=='B')
    		{
    			if(las==1) ++now;
    			else now=1;
    			las=1;
    			std::swap(bo,bd);
    			if(now==ans)
    			{
    				int a=now&1?bo:bd,b=now&1?bd:bo;
    				if(now==i) std::swap(a,b);
    				std::cout<<name[a]<<' '<<name[b]<<'
    ';
    			}
    			q.push(wd), wd=wo, wo=q.front(), q.pop();
    		}
    		else
    		{
    			if(las==0) ++now;
    			else now=1;
    			las=0;
    			std::swap(wo,wd);
    			if(now==ans)
    			{
    				int a=now&1?wo:wd,b=now&1?wd:wo;
    				if(now==i) std::swap(a,b);
    				std::cout<<name[a]<<' '<<name[b]<<'
    ';
    			}
    			q.push(bd), bd=bo, bo=q.front(), q.pop();
    		}
    	
    
    	return 0;
    }
    

    D. Lost in Translation(BFS) √

    深度要最小:用BFS!深度最小时可以更新dis。
    怎么就容易忘了最简单的那种BFS分层呢。(注意一下状态数)

    //31ms	4000KB
    #include <bits/stdc++.h>
    #define pc putchar
    #define gc() getchar()
    using namespace std;
    typedef long long LL;
    const int N=1e5+5;
    
    bool vis[N];
    int dep[N];
    LL dis[N];
    struct Node2
    {
    	int x,dep;
    	LL val;
    };
    
    struct Node{
    	int to,val;
    };
    vector<Node> e[N];
    map<string,int> mp;
    
    inline int read()
    {
    	int now=0,f=1; char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-48,c=gc());
    	return now*f;
    }
    
    int main()
    {
    	int n=read()+1,m=read();
    	string s="English",t; mp[s]=1;
    	for(int i=2; i<=n; ++i) cin>>s, mp[s]=i;
    	int tot=n;
    	for(int i=1,u,v,w; i<=m; ++i)
    	{
    		cin>>s, cin>>t;
    		u=mp[s], v=mp[t], w=read();
    		e[u].push_back((Node){v,w}), e[v].push_back((Node){u,w});
    	}
    
    	static std::queue<Node2> q;
    	LL ans=0; q.push((Node2){1,0,0});
    	memset(dis,0x3f,sizeof dis);
    	for(int i=1; i<=n; ++i) dep[i]=N;
    	while(!q.empty())
    	{
    		Node2 p=q.front(); q.pop();
    		int x=p.x;
    		dep[x]=std::min(dep[x],p.dep);
    		if(p.dep==dep[x]) dis[x]=std::min(dis[x],p.val);
    		if(vis[x]) continue;
    		vis[x]=1;
    		for(auto v:e[x])
    			q.push((Node2){v.to,p.dep+1,v.val});
    	}
    	for(int i=1; i<=n; ++i)
    		if(!vis[i]) return puts("Impossible"),0;
    		else ans+=dis[i];
    	printf("%lld
    ",ans);
    	
    
    	return 0;
    }
    

    G. That's One Hanoi-ed Teacher(汉诺塔递归)

    需要复习一下汉诺塔。汉诺塔的递归是这样的:

    void DFS(int n,int a,int b,int c)//第n个圆盘从a->c
    {
    	if(n==1)
    	{
    		printf("%d: %d->%d
    ",n,a,c);
    		return;
    	}
    	DFS(n-1,a,c,b);
    	printf("%d: %d->%d
    ",n,a,c);
    	DFS(n-1,b,a,c);
    }
    

    总过程是,将圆盘(n-1)(a)移到(b),将圆盘(n)(a)移到(c),最后将圆盘(n-1)(b)移到(c)
    所以这个题,从(n)开始判断:

    • 如果(n)仍在(a)上,则还至少需(1)步将(n)移到(c),和(2^{n-1}-1)步将(n-1)个盘子从(b)移到(c),然后再看(n-1)是否已经从(a)移到(b)上;
    • 如果(n)(b)上,则不是最优解;
    • 如果(n)(c)上,则(n-1)已到过(b),再看(n-1)是否已从(b)移到(c)即可。

    类似地递归一下,注意修改当前的参数(a,b,c)就可以了。

    //30ms	0KB
    #include <bits/stdc++.h>
    #define pc putchar
    #define gc() getchar()
    typedef long long LL;
    const int N=105;
    
    int vis[N];
    LL ans;
    
    inline int read()
    {
    	int now=0,f=1; char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-48,c=gc());
    	return now*f;
    }
    bool DFS(int n,int a,int b,int c)
    {
    	if(!n) return 1;
    	if(vis[n]==a) return ans+=1ll<<(n-1),DFS(n-1,a,c,b);//n还在a,判断n-1是否已从a移到b去 
    	else if(vis[n]==c) return DFS(n-1,b,a,c);//n已经到c,判断n-1是否已从b移回到c去 
    	return 0;
    }
    
    int main()
    {
    	int a=read(); for(int i=1; i<=a; ++i) vis[read()]=1;
    	int b=read(); for(int i=1; i<=b; ++i) vis[read()]=2;
    	int c=read(); for(int i=1; i<=c; ++i) vis[read()]=3;
    	if(!DFS(a+b+c,1,2,3)) puts("No");
    	else printf("%lld
    ",ans);
    
    	return 0;
    }
    

    H. Vin Diagrams(模拟) √

    因为限制条件很多,所以直接从AB位置开始DFS,求出每个X属于的方阵,然后再对方阵里面的点DFS。至于交,可以先分别DFS整个A方阵和B方阵中的点,被DFS两次的点即交。
    然后想找到A或B方阵中的某个点,可以找到方阵的左上角((i,j)),那么((i+1,j+1))一定在该方阵中,从它开始DFS即可。

    //30ms	400KB
    #include <bits/stdc++.h>
    #define pc putchar
    #define gc() getchar()
    #define OK(x,y) (x>=1 && x<=n && y>=1 && y<=m)
    typedef long long LL;
    const int N=105,Way[5]={1,0,-1,0,1};//down,left,up,right
    
    int n,m,Ans[5],bel[N][N];//1:A 2:B 3:intersection
    char s[N][N];
    int vis[N][N],vis2[N][N];
    
    inline int read()
    {
    	int now=0,f=1; char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-48,c=gc());
    	return now*f;
    }
    void DFS(int x,int y,int val,int pre)
    {
    	int t=0;
    	for(int i=0; i<4; ++i)
    	{
    		int xn=x+Way[i],yn=y+Way[i+1];
    		if(OK(xn,yn)) t+=s[xn][yn]!='.';
    	}
    	if(t==4)
    	{
    		bel[x][y]=3;
    		for(int i=0; i<4; ++i)
    			if(i==pre)
    			{
    				int xn=x+Way[i],yn=y+Way[i+1];
    				if(OK(xn,yn)&&s[xn][yn]=='X'&&!bel[xn][yn]) DFS(xn,yn,val,i);
    			}
    	}
    	else
    	{
    		bel[x][y]=val, assert(t==2);
    		for(int i=0; i<4; ++i)
    		{
    			int xn=x+Way[i],yn=y+Way[i+1];
    			if(OK(xn,yn)&&s[xn][yn]!='.'&&(!bel[xn][yn]||bel[xn][yn]==3)) DFS(xn,yn,val,i);
    		}
    	}
    }
    void DFS2(int x,int y,int val)
    {
    	vis[x][y]+=val, vis2[x][y]=1;
    	for(int i=0; i<4; ++i)
    	{
    		int xn=x+Way[i],yn=y+Way[i+1];
    		if(OK(xn,yn)&&bel[xn][yn]!=val&&bel[xn][yn]!=3&&!vis2[xn][yn]) DFS2(xn,yn,val);
    	}
    }
    void Calc(int val)
    {
    	memset(vis2,0,sizeof vis2);
    	for(int i=1; i<=n; ++i)
    		for(int j=1; j<=m; ++j)//找一个最左上角的,它的右下一定在封闭图形里面 
    			if(bel[i][j]==val) {DFS2(i+1,j+1,val); return;}
    }
    
    int main()
    {
    	int n=read(),m=read(); ::n=n, ::m=m;
    	for(int i=1; i<=n; ++i) scanf("%s",s[i]+1);
    	for(int i=1; i<=n; ++i)
    		for(int j=1; j<=m; ++j)
    			if(s[i][j]=='A'||s[i][j]=='B') DFS(i,j,s[i][j]=='A'?1:2,0);
    	Calc(1), Calc(2);
    
    	for(int i=1; i<=n; ++i)
    		for(int j=1; j<=m; ++j) if(!bel[i][j]) ++Ans[vis[i][j]];
    	printf("%d %d %d
    ",Ans[1],Ans[2],Ans[3]);
    	
    
    	return 0;
    }
    

    ------------------------------------------------------------------------------------------------------------------------
    无心插柳柳成荫才是美丽
    有哪种美好会来自于刻意
    这一生波澜壮阔或是不惊都没问题
    只愿你能够拥抱那种美丽
    ------------------------------------------------------------------------------------------------------------------------
  • 相关阅读:
    无缝滚动效果实现
    js模拟滚动条插件一二
    powerDesigner15.1破解
    解决asp.net 中GridView中隐藏过长的数据(使用ToolTip)
    IE6下弹出div覆盖select下拉框
    sql中的常用函数结合实现截取替换功能
    【.NET重修计划】数组,集合,堆栈的问题
    Redis可视化工具推荐
    Redis中String类型的相关命令操作
    Redis的五大数据类型以及key的相关操作命令
  • 原文地址:https://www.cnblogs.com/SovietPower/p/14351407.html
Copyright © 2020-2023  润新知