• 洛谷P1053 篝火晚会


    P1053 篝火晚会

    题目描述

    佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”。在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会。一共有n个同学,编号从1到n。一开始,同学们按照1,2,……,n的顺序坐成一圈,而实际上每个人都有两个最希望相邻的同学。如何下命令调整同学的次序,形成新的一个圈,使之符合同学们的意愿,成为摆在佳佳面前的一大难题。

    佳佳可向同学们下达命令,每一个命令的形式如下:

    (b1, b2,... bm -1, bm)

    这里m的值是由佳佳决定的,每次命令m的值都可以不同。这个命令的作用是移动编号是b1,b2,…… bm的这m个同学的位置。要求b1换到b2的位置上,b2换到b3的位置上,……,要求bm换到b1的位置上。执行每个命令都需要一些代价。我们假定如果一个命令要移动m个人的位置,那么这个命令的代价就是m。我们需要佳佳用最少的总代价实现同学们的意愿,你能帮助佳佳吗?

    输入输出格式

    输入格式:

    输入文件fire.in的第一行是一个整数n(3 <= n <= 50000),表示一共有n个同学。其后n行每行包括两个不同的正整数,以一个空格隔开,分别表示编号是1的同学最希望相邻的两个同学的编号,编号是2的同学最希望相邻的两个同学的编号,……,编号是n的同学最希望相邻的两个同学的编号。

    输出格式:

    输出文件fire.out包括一行,这一行只包含一个整数,为最小的总代价。如果无论怎么调整都不能符合每个同学的愿望,则输出-1。

    输入输出样例

    输入样例#1:
    4
    
    3 4
    
    4 3
    
    1 2
    
    1 2
    
    输出样例#1:
    2

    说明

    对于30%的数据,n <= 1000;

    对于全部的数据,n <= 50000。

    2005提高组第三题

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #define maxn 50010
    using namespace std;
    map<string,bool>vis;
    map<string,bool>ok;
    int n,a[maxn],b[maxn],ans=0x7fffffff;
    void dfs(string now,int sum){
        if(sum>=ans)return;
        if(sum>n)return;
        if(ok[now]){
            ans=min(ans,sum);
            return;
        }
        string to="";
        for(int len=2;len<=n;len++){
            for(int l=0;l<=n-len;l++){
                int r=l+len-1;
                to="";
                to=to+now.substr(0,l);
                to=to+now[r];
                to=to+now.substr(l,len-1);
                to=to+now.substr(r+1,n-r);
                if(vis[to])continue;
                dfs(to,sum+len);
            }
        }
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);
        string s="";
        //char ch=a[1]+'0';
        s=s+'1';
        s=s+(char)(a[1]+'0');
        for(int i=2;i<n;i++){
            int now=s[i-1]-'0';
            if(s[i-2]==(char)(a[now]+'0'))s=s+(char)(b[now]+'0');
            if(s[i-2]==(char)(b[now]+'0')) s=s+(char)(a[now]+'0');
        }
        bool flag=0;
        if(s.length()!=n)flag=1;
        ok[s]=1;
        string ss="";
        for(int i=1;i<n;i++){
            ss=ss+s[n-1];
            ss=ss+s.substr(0,3);
            ok[ss]=1;
            s=ss;ss="";
        }
        s="1";
        s=s+(char)(b[1]+'0');
        for(int i=2;i<n;i++){
            int now=s[i-1]-'0';
            if(s[i-2]==(char)(a[now]+'0'))s=s+(char)(b[now]+'0');
            if(s[i-2]==(char)(b[now]+'0')) s=s+(char)(a[now]+'0');
        }
        if(s.length()==n)flag=0;
        ok[s]=1;
        ss="";
        for(int i=1;i<n;i++){
            ss=ss+s[n-1];
            ss=ss+s.substr(0,3);
            ok[ss]=1;
            s=ss;ss="";
        }
        if(flag){
            puts("-1");
            return 0;
        }
        string s1="";
        for(int i=1;i<=n;i++)s1=s1+(char)(i+'0');
        vis[s1]=1;
        dfs(s1,0);
        printf("%d",ans);
    }
    10分 暴力
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    #include<algorithm>
    #define maxn 50010
    using namespace std;
    int n,a[maxn],b[maxn],p[maxn],k,f[maxn],s,ans,l;
    bool vis[maxn];
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);
        k=0;l=1;
        for(int i=b[1];i!=1&&vis[i]==0;){
            p[++k]=l;vis[i]=1;
            if(a[i]==l){l=i;i=b[i];}
            else{l=i;i=a[i];}
        }
        p[++k]=l;
        if(k!=n){
            puts("-1");return 0;
        }
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++){
            if(p[i]>=i)f[p[i]-i]++;
            else f[p[i]+n-i]++;
        }
        for(int i=0;i<n;i++)ans=max(ans,f[i]);
        
        k=0;l=1;
        for(int i=a[1];i!=1;){
            p[++k]=l;
            if(a[i]==l){l=i;i=b[i];}
            else{l=i;i=a[i];}
        }
        p[++k]=l;
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++){
            if(p[i]>=i)f[p[i]-i]++;
            else f[p[i]+n-i]++;
        }
        for(int i=0;i<n;i++)ans=max(ans,f[i]);
        printf("%d",n-ans);
    }
    100分
  • 相关阅读:
    数组名作为左值和右值的区别
    指针与数组区别
    linux服务器开启免密登录
    mssql清空数据和添加主键约束语法
    链接服务器方式查视图导致索引失效的解决方法
    sqlserver2008r2 版本数据库迁移到2019版本导致查询效率慢的解决方法
    lnmp一键安装访问default目录可行,访问其它站点报404错误
    lPeer reports incompatible or unsupported protocol version.
    yum安装时出现:Cannot retrieve metalink for repository: epel. Please verify its path and try again
    Linux Centos7.4 下安装 LAMP环境及配置(php5.6,mysql5.7)
  • 原文地址:https://www.cnblogs.com/thmyl/p/7665912.html
Copyright © 2020-2023  润新知