洛谷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分

 

posted @ 2017-10-14 10:30  Echo宝贝儿  阅读(227)  评论(0编辑  收藏  举报