| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 450 人关注过本帖
标题:联谊会的游戏
只看楼主 加入收藏
zxiq_to
Rank: 1
等 级:新手上路
帖 子:15
专家分:3
注 册:2012-8-18
结帖率:100%
收藏
 问题点数:0 回复次数:5 
联谊会的游戏
描述 Description
WGSZ举办了一次联谊会,有N个男生和N个女生参加.这次的联谊会安排了一个小节目,好让每个加者都可以找到心仪的对象,小节目的流程如下:
1.每个参加者都有一个编号,且保证一个号码有且仅出现2次,代表一个男生和一个女生拥有相同的编号.这2N个参赛者拿到自己的号码后就会顺序进入一个队列.该队列将在输入之中给出.
2.每个人都要去找跟自己编号相同的异性,但是找的时候每次只能和自己的左右两边的人交换位置.例如:1 2 3 1 2 3这样一个队列,处在第4号的编号为1的人只能和他左边的第三号位的人交换或者和第五号位的交换位置.不可跨越换位
3.如果一个人找到了和自己编号相同的异性,那么这两个人就高高兴兴的去舞池跳舞去了,此时这两人会迅速离队,后面的人会填充这时空缺的位置.

由于人数众多,主办方希望总交换位置的次数尽量小,所以,主办方找到了你,希望你能帮他解决这个问题.

输入格式 InputFormat
  第一行:1个数 N 表示一共有N个编号 2N个人参加
  以下2*N行:每行一个数 代表处于第i号的人的编号

输出格式 OutputFormat
  第一行:最少的交换次数.

样例输入:
3
1
2
3
1
2
3

样例输出 SampleOutput:
3

数据范围和注释 Hint
首先队列是   1 2 3 1 2 3
第一次交换   1 2 3 2 1 3
第二次交换   1 3 2 2 1 3
此时可以消去 1 3 1 3
第三次交换   1 1 3 3
此时可以消去 3 3
此时可以消去 //
所以最少交换次数为3

数据规模:
10%的数据 N<=5
30%的数据 N<=10 且保证答案在10以内
60%的数据 N<=100
100%的数据 N<=50000 且保证答案在maxlongint范围以内


时间限制 TimeLimitation
1s
  这个题目大家做下。
搜索更多相关主题的帖子: 联谊会 
2012-11-04 09:08
w527705090
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:11
帖 子:441
专家分:1882
注 册:2011-6-28
收藏
得分:0 
这个不会。。。。帮顶!!

有心者,千方百计;无心者,千难万难。
2012-11-04 14:23
zxiq_to
Rank: 1
等 级:新手上路
帖 子:15
专家分:3
注 册:2012-8-18
收藏
得分:0 
这么久了还没人解答,我知道不是不会是没人看
2012-11-24 16:24
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
从左到右扫描,从第一个开始,每次遇到相同的就计算它们之间的距离,然后它们两出局

贪心证明:
对于某个id来说,他不断的交换位置并不影响其他id的"相对位置“,即之后计算其他id的代价不受其影响,所以贪心成立

由于n《=50000,直接查找O(n^2)算法会出问题,可以用树状数组维护,时间复杂度达到O(nlogn)
2012-11-25 00:15
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
程序代码:
#include <stdio.h>
#define Max 50000

int i,j,n,ans,total,num[Max+1],a[Max+1];

void add(int p)
{
     while (p<=Max)
     {
           a[p]++;
           p=p+(p&(-p));
     }
}

void minus(int p)
{
     while (p<=Max)
     {
           a[p]--;
           p=p+(p&(-p));
     }
}

int get(int p)
{
    int t=0;
    while (p>=1)
    {
          t+=a[p];
          p=p-(p&(-p));
    }
    return t;
}

int main()
{
    memset(num,0,sizeof(num));
    memset(a,0,sizeof(a));
    ans=0; total=0;
    scanf("%d",&n);
    for (i=0; i<n+n; i++)
    {
        scanf("%d",&j);
        if (num[j]==0)
        {
                      add(++total);
                      num[j]=total;
        }
        else
        {
                      ans+=get(Max)-get(num[j]);
                      minus(num[j]);
        }
    }
    printf("%d\n",ans);
    system("pause");
}
    
2012-11-25 10:03
zxiq_to
Rank: 1
等 级:新手上路
帖 子:15
专家分:3
注 册:2012-8-18
收藏
得分:0 
时隔八年,我又回来了。

当初完全做不出的题目,现在看起来好理解多了
2020-08-15 05:13
快速回复:联谊会的游戏
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015230 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved