您的位置:首页 > 其它

10月集训test5

2017-10-16 19:51 369 查看
嗯,隔了这么久,都有些记不太清当时考场上的心理活动了。。。

不过貌似,考得还可以?(大概就是说第一题成功A了,后面成功拿到暴力分。。。)

哦还是WKL凯爷出的题,感谢撒花~

上题。

1.鱼群分裂

豆豆养了一群鳕鱼。这些鳕鱼在收到惊吓的情况下会分成很多小鱼群四处逃窜。豆豆观察到这些鳕鱼鱼群分裂很有意思。如果当前的鱼群有 N 只鱼,并且可以分裂成两个鱼群使得这两个鱼群中的鱼的数量差恰好为 K ,那么这群鱼就会分裂成两群数量相差 K 的鱼群,否则就不会分裂。(就是这么奇怪)

豆豆想知道最终会分裂成多少群鱼?

输入格式

第一行两个整数 N, K 代表初始时的第一群鱼的数量和数值 K ;

输出格式

输出一个整数表示最终形成的鱼群数量。

样例数据

输入

6 2

输出

3

备注

【样例说明】

6 分裂成 4 和 2 ,4 分裂成 1 和 3 。

【数据范围】

对于 50% 的数据,K 为奇数;

对于 100% 的数据,N≤10^9,K≤1000。

这种题应该不用多说吧,简单明了,就是不断的分啊分啊分啊,将分出来的两份再分阿分啊分啊……以此类推。

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;

long long n,k,ans;

inline void zql(int x)
{
if((x+k)%2==0&&x-k>0)
{
ans++;
zql((x+k)/2);
zql((x-k)/2);
}
}

int main()
{
//freopen("split.in","r",stdin);
//freopen("split.out","w",stdout);

cin>>n>>k;
zql(n);
cout<<ans+1<<endl;
return 0;
}


2.跑步

企鹅国正在举办全面运动会,第一项比赛就是跑步。N 个人在圆形跑道上跑步,他们都有各自的速度和起点。但这个跑步规则很奇怪,当两个人相遇的时候编号较小的就会出局,当场上剩下最后一个人的时候跑步就结束了。豆豆想知道多长时间游戏会结束?

输入格式

第一行一个整数 T 表示数据组数;

每组数据的第一行是两个整数 N 和 L ,表示参赛人数以及跑道长度。

接下来一行有 N 个不同的整数 Di,表示每个人的起点。

接下来一行有 N 个不同的整数 Vi,表示每个人的跑步速度,如果速度为负数,就是在反着跑。

输出格式

对于每组数据,以最简分数形式表示游戏结束的时间。

样例数据

输入

2

2 4

0 2

3 2

10 100

56 89 62 71 7 24 83 1 47 52

9 -16 34 -38 47 49 -32 17 39 -9

输出

2/1

37/7

备注

【数据范围】

对于 30% 的数据,2≤n≤100, 1≤L≤200;

对于 60% 的数据,2≤n≤10^3。

对于 100% 的数据,2≤n≤10^5,T≤5, 1≤L≤10^9, 0≤Di

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int Read()
{
int i=0,f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9') {i=i*10+(c-'0'); c=getchar();}
return f*i;
}
int t,n,m,vk,dk,v[100005],l[100005],r[100005];
bool vis[100005]={false};
struct node
{int id,str;friend bool operator <(const node &a,const node &b){return a.str<b.str;}}d[100005];
inline void calc(int i,int j)
{
int x,y;
x=d[i].id;y=d[j].id;
if(d[i].str>d[j].str)
{if(v[x]>v[y])dk=(d[j].str+m-d[i].str),vk=(v[x]-v[y]);if(v[x]<v[y])dk=(d[i].str-d[j].str),vk=(v[y]-v[x]);}
if(d[i].str<d[j].str)
{if(v[x]>v[y])dk=(d[j].str-d[i].str),vk=(v[x]-v[y]);if(v[x]<v[y])dk=(d[i].str+m-d[j].str),vk=(v[y]-v[x]);}
}
struct data
{
int i,j;
data(int i,int j):i(i),j(j){}
friend bool operator <(const data &a,const data &b)
{
int x1,y1,x2,y2;
calc(a.i,a.j);x1=dk,y1=vk;calc(b.i,b.j);x2=dk,y2=vk;
return (double)x1/(double)y1>(double)x2/(double)y2;
}
};
int gcd(int a,int b){if(b==0) return a;return gcd(b,a%b);}
int main()
{

t=Read();
while(t--)
{
n=Read(),m=Read();
for(int i=1;i<=n;++i)d[i].str=Read(), d[i].id=i;
for(int i=1;i<=n;++i)v[i]=Read();sort(d+1,d+n+1);
for(int i=1;i<=n;++i)
{
if(i==1) l[i]=n;else l[i]=(i-1+n)%n;
if(i==n-1) r[i]=n;else r[i]=(i+1)%n;
}
priority_queue<data >q;
for(int i=1;i<=n;++i)
{
if(i==n-1) q.push(data(i,n));
else q.push(data(i,(i+1)%n));
}
memset(vis,0,sizeof(vis));int a,b;
while(!q.empty())
{
data now=q.top();q.pop();
int i=now.i,j=now.j;
if(vis[i]||vis[j]) continue;
if(d[j].id>d[i].id)swap(i,j);
calc(i,j);a=dk,b=vk;vis[j]=1;
int LL=l[j],RR=r[j];
r[LL]=RR,l
b4e8
[RR]=LL;
if(LL!=i)q.push(data(LL,i));
if(RR!=i)q.push(data(i,RR));
}
int ccc=gcd(a,b);
cout<<a/ccc<<"/"<<b/ccc<<endl;
}
return 0;
}


3.拆墙

地主的傻儿子豆豆家很大很大,由很多个区域组成。其中有不少封闭的区域,豆豆觉得很不爽于是决定拆墙,把家打通使得他可以访问到每一个区域(包括家外面无限大的区域)。我们用 N 个端点和 M 条边来描述豆豆的家。第 i 个端点的坐标为(xi,yi),第 i 条边连接端点 Ai 和 Bi,拆除所需要花费的力气为 Ci 。保证所有边只在端点相交,也就是这是一个平面图,也没有重边和自环。

现在豆豆想知道他最少一共需要花费多少力气?

输入格式

第一行一个整数 T 表示数据组数。

每组数据第一行两个整数 N,M 。

接下来 N 行每行两个整数 Xi 和 Yi。

接下来 M 行每行三个整数 Ai,Bi,Ci。

输出格式

每组数据输出两个整数表示最少拆除的墙的数量和拆墙最少需要多少的力气。注意所有墙可能不互相连通。

样例数据

输入

1

4 4

-1 -1

-1 1

1 1

1 -1

1 2 1

2 3 2

3 4 1

4 1 2

输出

1 1

备注

【数据范围】

对于 30% 的数据,N,M≤10,T=10;

对于 70% 的数据,N≤5000, M≤10000,T=1;

对于 100% 的数据,N≤100000;M≤200000;ΣN≤300000;ΣM≤500000;|xi|,|yi|≤100000;0≤wi≤10000,T=3。

并查集吗?先将权值全部加上,再减去不必要的权值。

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;

struct node
{
int x,y,z;
}a[500010];
int t,n,m,x;
int fa[100010];

inline int read()
{
int i=0,f=1;
char c;
for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-') f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0';
return i*f;
}

inline int getfa(int i)
{
if(fa[i]!=i)
fa[i]=getfa(fa[i]);
return fa[i];
}

inline bool comp(const node &a,const node &b)
{
return a.z>b.z;
}

int main()
{
//freopen("wall.in","r",stdin);
//freopen("wall.out","w",stdout);

t=read();
while(t--)
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
int x;
x=read(),x=read();
fa[i]=i;
}
int ans1=m,ans2=0;
for(int i=1;i<=m;i++)
{
a[i].x=read();
a[i].y=read();
a[i].z=read();
ans2+=a[i].z;
}
sort(a+1,a+m+1,comp);
for(int i=1;i<=m;i++)
{
int fx=getfa(a[i].x),fy=getfa(a[i].y);
if(fx!=fy)
{
fa[fy]=fx;
ans2-=a[i].z;
ans1--;
}
}
cout<<ans1<<" "<<ans2<<endl;
}
return 0;
}


<手动再见>

来自2017.10.13.

——我认为return 0,是一个时代的终结。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  并查集