zoukankan      html  css  js  c++  java
  • CF578E. Walking!

    题目大意

    题解

    把一个点拆成两个点,L->R和R->L连成二分图,n-匹配数就是链数,链数-1就是答案

    所以贪心匹配就行了,最后根据首尾LR情况有4种,LR和RL在存在LL或RR时都可以消掉

    如果同时存在LR和RL且没有LL和RR就会挂掉,所以在找的时候优先构出LL和RR即可

    这样的话就不会同时有LR和RL,因为画一下几种情况发现都会先构出LL或RR

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define ll long long
    //#define file
    using namespace std;
    
    int a[100001],nx[100001],d[2][2][100001],t[2][2],n,i,j,k,l,ans,s,S;
    char st[100001];
    bool bz[100001];
    
    void dg(int t)
    {
    	printf("%d ",t),S^=1;
    	if (nx[t]) dg(nx[t]);
    }
    
    int main()
    {
    	#ifdef file
    	freopen("CF578E.in","r",stdin);
    	#endif
    	
    	scanf("%s",st+1),n=strlen(st+1);
    	fo(i,1,n) a[i]=st[i]=='R';
    	fo(i,1,n)
    	if (t[a[i]][a[i]^1])
    	{
    		nx[d[a[i]][a[i]^1][t[a[i]][a[i]^1]]]=i;
    		--t[a[i]][a[i]^1];
    		d[a[i]][a[i]][++t[a[i]][a[i]]]=i;
    	}
    	else
    	if (t[a[i]^1][a[i]^1])
    	{
    		nx[d[a[i]^1][a[i]^1][t[a[i]^1][a[i]^1]]]=i;
    		--t[a[i]^1][a[i]^1];
    		d[a[i]^1][a[i]][++t[a[i]^1][a[i]]]=i;
    	}
    	else
    	d[a[i]][a[i]][++t[a[i]][a[i]]]=i,++ans,bz[i]=1;
    	
    	printf("%d
    ",ans-1);
    	memset(t,0,sizeof(t));
    	fo(i,1,n)
    	if (bz[i])
    	{
    		for (j=i; nx[j]; j=nx[j]);
    		d[a[i]][a[j]][++t[a[i]][a[j]]]=i;
    	}
    	s=t[1][1]>t[0][0];
    	while (t[0][0] || t[1][1])
    	{
    		if (t[0][1] || t[1][0])
    		{
    			if (!s)
    			{while (t[0][1]) dg(d[0][1][t[0][1]]),--t[0][1];}
    			else
    			{while (t[1][0]) dg(d[1][0][t[1][0]]),--t[1][0];}
    		}
    		dg(d[s][s][t[s][s]]),--t[s][s];
    		if (t[0][1] || t[1][0])
    		{
    			if (!s)
    			{while (t[1][0]) dg(d[1][0][t[1][0]]),--t[1][0];}
    			else
    			{while (t[0][1]) dg(d[0][1][t[0][1]]),--t[0][1];}
    		}
    		s^=1;
    	}
    	while (t[0][1]) dg(d[0][1][t[0][1]]),--t[0][1];
    	while (t[1][0]) dg(d[1][0][t[1][0]]),--t[1][0];
    	printf("
    ");
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    时间复杂度计算
    SQL Server2012编程入门经典(第四版) 读书笔记
    一些编程试题
    Qt 对话框显示控制按钮
    vc++创建文件目录
    配置ubuntu虚拟机备忘
    Qt QThread 多线程使用
    Qt 程序等待多长时间执行Sleep
    Qt 数字和字符处理总结
    c++ 文件utf-8格式
  • 原文地址:https://www.cnblogs.com/gmh77/p/13636162.html
Copyright © 2011-2022 走看看