Seating Chart Gym - 101656H —— 逆序对

Seating Chart
Bilbo’s birthday is coming up, and Frodo and Sam are in charge of all the party planning! They
have invited all the hobbits of Middle Earth to the party, and everyone will be sitting in a single
row at an extremely long dining table.
However, due to poor communication, Frodo and Sam have each independently put together a
seating chart for all the hobbits at the dining table. Help Frodo and Sam find out how similar their
seating charts are by counting the total number of distinct pairs of hobbits who appear in different
orders in the two charts.
Input
The input file will contain multiple test cases. Each test case begins with a single line containing
an integer N (1 ≤ N ≤ 100,000) indicating the number of hobbits. The next two lines represent
Frodo’s and Sam’s seating charts, respectively. Each seating chart is specified as a single line of
N unique alphabetical strings; the set of strings in each line are guaranteed to be identical. The
end-of-input is denoted by a line containing the number 0.
Output
For each input test case, output a single integer denoting, out of the N choose 2 distinct pairs of
hobbits, how many pairs appear in different orders in Frodo’s and Sam’s seating arrangements.
Sample Input Sample Output
3
Frodo Sam Bilbo
Sam Frodo Bilbo
5
A B C D E
B A D E C
0
1
3

题意:

给你n个人一开始的序列和最终序列,问你有多少对人换了位置。

题解:

对一开始给你的序列做标记,然后就是最普通的逆序对了,从后往前插,看看有多少比他小的数就好了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
map<string,int>map1;
int b[N],num[N];
int lowbit(int x)
{
    return x&(-x);
}

void add(int x)
{
    for(int i=x;i<N;i+=lowbit(i))
        num[i]++;
}
int query(int x)
{
    int ans=0;
    for(int i=x;i;i-=lowbit(i))
        ans+=num[i];
    return ans;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        map1.clear();
        memset(num,0,sizeof(num));
        int ct=0;
        string s;
        for(int i=1;i<=n;i++)
            cin>>s,map1[s]=++ct;
        for(int i=1;i<=n;i++)
            cin>>s,b[i]=map1[s];
        ll ans=0;
        for(int i=n;i>=1;i--)
        {
            ans+=(ll)query(b[i]);
            add(b[i]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值