您的位置:首页 > 其它

【NOIP 2013 DAY.1】火柴排队【codevs 3286】

2016-05-02 11:51 267 查看
分析:贪心策略。第一行第一小对第二行第一小、第一行第二小对第二行第二小。。。类推。

即:排序,求排序的次数。

(归并排序求逆序对)【记录交换的次数即是答案】*推荐使用归并。本题最优解法。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;

const int mod=99999997;
int a[100005],b[100005];
int l[100005],r[100005];
int s[100005],t[100005];
int rr[100005];
int sum;
int n;

void m_sort(int x,int y)
{
if(y-x>1)
{
int m=x+(y-x>>1);
int p=x,q=m,i=x;
m_sort(x,m);
m_sort(m,y);
while(p<m || q<y)
{
if(q>=y || (p<m && s[p]<=s[q])) t[i++]=s[p++];
else
{
t[i++]=s[q++];
sum+=m-p;
}
}
for(i=x;i<y;i++) s[i]=t[i];
}
sum%=mod;
}

int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",a+i);
l[i]=a[i];
}
for(int i=0;i<n;i++)
{
scanf("%d",b+i);
r[i]=b[i];
}
sort(l,l+n);
sort(r,r+n);
for(int i=0;i<n;i++)
{
int locB=lower_bound(r,r+n,b[i])-r;
rr[locB]=i;
}
for(int i=0;i<n;i++)
{
int locA=lower_bound(l,l+n,a[i])-l;
s[rr[locA]]=i;
}
m_sort(0,n);
printf("%d",sum);
return 0;
}


(线段树/树状数组求逆序对)

#include<iostream>

#include<cstdlib>

#include<cstdio>

#include<algorithm>

using namespace std;

struct stone

{

int num,c;

} l1[100010],l2[100010];

int n,c[100010];

int tree[100010];

int lowbit(int x)

{

return (-x)&x;

}

bool cmp(stone x,stone y)

{

return x.c<y.c;

}

void insert(int x)

{

while(x<=n)

{

tree[x]++;

x+=lowbit(x);

}

}

int get(int x)

{

int sum=0;

while(x>0)

{

sum+=tree[x];

x-=lowbit(x);

}

return sum;

}

int main()

{

cin>>n;

for(int i=1;i<=n;i++)

{

scanf("%d",&l1[i].c);

l1[i].num=i;

}

for(int i=1;i<=n;i++)

{

scanf("%d",&l2[i].c);

l2[i].num=i;

}

sort(l1+1,l1+n+1,cmp);

sort(l2+1,l2+n+1,cmp);

long long cnt=0;

for(int i=1;i<=n;i++)

{

c[l1[i].num]=l2[i].num;

}

//for(int i=1;i<=n;i++) cout<<c[i]<<" ";

for(int i=1;i<=n;i++)

{

insert(c[i]);

cnt+=i-get(c[i]);

cnt=cnt%99999997;

}

cout<<cnt;

return 0;

}


std::

#include<cstdio>
#include<algorithm>
#define MAXN 100000
using namespace std;
struct node
{
int x,cnt;
}A[MAXN+10],B[MAXN+10];
int aa[MAXN+10];
int T[MAXN+10];
int ans=0;
bool cmp(node a,node b)
{
return a.x<b.x;
}
void marge(int l,int mid,int r)
{
int i=l,j=mid+1,k;
for(k=l;k<=r;k++)
if((i<=mid)&&((j>r)||(aa[i]<=aa[j])))
T[k]=aa[i++];
else{
T[k]=aa[j++];
ans+=mid-i+1;
ans%=99999997;
}
for(i=l;i<=r;i++)
aa[i]=T[i];
}
void margef(int l,int r)
{
if(l<r)
{
int mid=(l+r)/2;
margef(l,mid);
margef(mid+1,r);
marge(l,mid,r);
}
}
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
int n,i;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&A[i].x);
A[i].cnt=i;
}
for(i=1;i<=n;i++)
{
scanf("%d",&B[i].x);
B[i].cnt=i;
}
sort(A+1,A+1+n,cmp);
sort(B+1,B+1+n,cmp);
for(i=1;i<=n;i++)
aa[A[i].cnt] = B[i].cnt;
margef(1,n);
printf("%d\n",ans%99999997);
return 0;
}
my ac code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 100010
int n;
int aa[maxn],T[maxn];
typedef struct{
int val,id;
}node;
node a[maxn],b[maxn];
int ans;
bool cmp(node A,node B)
{
return A.val<B.val;
}
void marge(int l,int r)
{
if(l==r)return;
int mid=(l+r)/2;
marge(l,mid);
marge(mid+1,r);
int i=l,j=mid+1,k;
for(k=l;k<=r;k++)
{
if((i<=mid)&&((j>r)||aa[i]<=aa[j]))T[k]=aa[i++];
else
{
T[k]=aa[j++];
ans+=mid-i+1;
ans%=99999997;
}
}
for(i=l;i<=r;i++)aa[i]=T[i];
}
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].val);
a[i].id=i;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i].val);
b[i].id=i;
}
std::sort(a+1,a+1+n,cmp);
std::sort(b+1,b+1+n,cmp);
for(int i=1;i<=n;i++)aa[a[i].id]=b[i].id;
marge(1,n);
printf("%d\n",ans%99999997);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: