Poj 1827 http://poj.org/problem?id=1827
题意:
输入 第一行,两个数,N 怪物数量, M 箱子表编号范围 ,下行,N个数,怪物拿起卡片编号,在下一行,N个,怪物的力量
看似简单的题目,却用到并查集,如果使用标记,在一个一个查找,会 TLE ,还是并查集高效,A 了一个下午,还是百度给力啊
同时,这一题,复习了结构体的定义,结构体的sort排序。。
并查集的代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std ;
const int N = 50001 ;
struct Node
{
int d, s;
} mons[N];
int n, m, p[N];
int cmp(Node a, Node b)
{
if (a.s != b.s)
{
return a.s > b.s ;
}
return a.d > b.d ;
}
int find(int x)
{
if (x != p[x])
{
p[x] = find(p[x]) ;
}
return p[x] ;
}
void Un_set(int x, int y)
{
int rx = find(x) , ry = find(y) ;
p[ry] = p[rx] ;
//printf("p[%d] = p[%d]\n",rx,ry);
}
int main()
{
while (~scanf("%d%d", &n, &m) && (n + m))
{
for (int i = 1; i <= n; i++)
{
scanf("%d", &mons[i].d) ;
}
for (int i = 1; i <= n; i++)
{
scanf("%d", &mons[i].s) ;
}
sort(mons + 1, mons + n + 1, cmp);
for (int i = 0; i <= m; i++)
{
p[i] = i ;
}
int sum = 0 ;
for (int i = 1; i <= n; i++)
{
int rd = find(mons[i].d);
//printf("find(mons[i].d = %d) = %d\n",mons[i].d,rd);
if (rd == 0)
{
//printf("s = %d\n", mons[i].s);
sum += mons[i].s ;
continue ;
}
Un_set(rd - 1, mons[i].d);
}
printf("%d\n", sum);
}
return 0 ;
}
自己的标记,查找代码,效率低,还是错误的。。。。。。。
#include<stdio.h>
#include<algorithm>
using namespace std;
int bleg[50005] = {0};
typedef struct mon
{
int s;
int d;
}mon;
bool cmp(mon mon1,mon mon2)
{
if(mon1.s < mon2.s) return mon1.s > mon2.s;
else if(mon1.s == mon2.s) return mon1.d>mon2.d;
}
int main()
{
mon mon[50005];
int n,m,i;
while(~scanf("%d %d",&n,&m) && m+n!=0)
{
bleg[0] = 1;
int sum = 0;
for(i=1;i<=n;i++)
{
scanf("%d",&mon[i].d);
}
for(i=1;i<=n;i++)
{
scanf("%d",&mon[i].s);
}
sort(mon+1,mon+n+1,cmp);
//for(i=1;i<n;i++) printf("%d %d\n",mon[i].d,mon[i].s);
//printf("\n");
for(i = 1;i<=n;i++)
{
int k = 0;
if(mon[i].d>m) sum += mon[i].s;
else if(bleg[mon[i].d] == 0)
{
bleg[mon[i].d] = 1;
}
else
{
k = 0;
//printf("jin er %d\n",mon[i].d);
while(bleg[mon[i].d-k]!=0)
{
//printf("jin san %d\n",mon[i].d);
//printf("xiangjianhou%d\n",mon[i].d - k);
if(mon[i].d - k == 0)
{
//printf("%d %d\n",mon[i].d,k);
sum+=mon[i].s;
break;
}
k++;
}
//printf("chulai%d\n",mon[i].d - k);
bleg[mon[i].d-k] = 1;
}
}
printf("%d\n",sum);
}
}
这个的查找代码是正确的
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef struct mon
{
int s;
int d;
}mon;
int cmp( const void *a , const void *b )
{
mon *c = (mon *)a;
mon *e = (mon *)b;
if(c->s != e->s) return e->s - c->s;
else return e->d - c->d;
}
int main()
{
mon mn[50005];
int n,m,i;
while(~scanf("%d %d",&n,&m) && m+n!=0)
{
int bleg[50005] = {0};
memset(&mn,0,sizeof(mon));
bleg[0] = 1;
int sum = 0;
for(i=0;i<n;i++)
{
scanf("%d",&mn[i].d);
}
for(i=0;i<n;i++)
{
scanf("%d",&mn[i].s);
}
qsort(mn,n,sizeof(mon),cmp);
/*
for(i=0;i<n;i++) printf("%d %d\n",mn[i].d,mn[i].s);
printf("\n");
*/
for(i = 0;i<n;i++)
{
int k = 0;
if(mn[i].d > m) sum += mn[i].s;
else if(bleg[mn[i].d] == 0)
{
bleg[mn[i].d] = 1;
}
else
{
int k ,t = 0;
for(k = mn[i].d; k>0; k--)
{
if(bleg[k] == 0)
{
bleg[k] = 1;
t = 1;
break;
}
if(bleg[k-1] == 0)
{
bleg[k-1] = 1;
t = 1;
break;
}
k = k - 1;
}
if(t==0)
{
sum += mn[i].s;
//printf("mn[%d] = %d\n",i,mn[i].s);
}
}
}
printf("%d\n",sum);
}
}
/*
7 7
6 4 4 2 4 3 4
10 70 20 60 30 50 40
*/