您的位置:首页 > 其它

10月集训test19

2017-11-08 18:09 239 查看
所以我来补上前一天的啦~

上题。

1.数集

其实原本是想到了用队列的。。。但是忘了可以分成两个队列,并且两个队列一定是严格单调递增的。。。。。

只是注意要去重。。这个不难,对比两个队列如今枚举这一位的大小即可,将小的那位往后移一位,大的那位不移就好了。

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

int a,n,t,two,three,rear;
long long t1,t2;
long long q[1000010];

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

while(scanf("%d%d",&a,&n)!=EOF)
{
rear=2;
q[1]=a;
two=1;three=1;
while(rear<=n)
{
t1=q[two]*2+1;
t2=q[three]*3+1;
t=min(t1,t2);
if(t1<t2)
two++;
else
three++;
if(t==q[rear-1])
continue;
q[rear]=t;
rear++;
}
printf("%lld\n",q
);
}
return 0;
}


2.序列操作

打暴力的话显然每次应该取最大的c[i]个。

正解用了一个神奇的贪心:先二分,二分出答案后判断可行不可行只考虑这样的贪心。先贪心取最开始前c[i]大的(不管后来是不是前c[i]大),如果不够,就往后取,扫一遍就可以了。。。。。

//80分暴力
#include<bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long
int c
,h
,n,num
,ma;

int main() {
//freopen("sequence.in","r",stdin);
//freopen("sequence.out","w",stdout);
int m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
for(int i=1;i<=m;i++) scanf("%d",&c[i]);
for(int i=1;i<=n;i++) {
num[h[i]]++;
ma=max(ma,h[i]);
}
for(register int i=1;i<=m;++i) {
int tot=0,pos=0;
for(register int j=ma;j>=1;--j) {
if(tot+num[j]>=c[i]) {
pos=j+1;
break;
}
tot+=num[j];
}
if(pos==0) {
printf("%d",i-1);
return 0;
}
int tmp=c[i]-tot;
num[pos-1]-=tmp;
num[pos-2]+=tmp;
for(register int j=pos;j<=ma;++j) {
num[j-1]+=num[j];
num[j]=0;
}
}
printf("%d",m);
}


3.图

题目说的很明确,是最小生成树。

正解。。。复杂的不要不要的,不过刻意暴力求LCA,暴力翻转边,也能AC掉这道题。

只上暴力。

//30分暴力,T掉了。
#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 u,v,w,y;
}bian[400010];
int n,q,a,b,m=0,x,k;
int f[100010];
long long ans;

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<<1)+(i<<3)+c-'0';
return i*f;
}

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

inline int gf(int x)
{
if(x==f[x])
return x;
f[x]=gf(f[x]);
return f[x];
}

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

n=read(),a=read(),b=read(),q=read();
for(int i=1;i<=a;i++)
{
bian[++m].u=read();
bian[m].v=read();
bian[m].w=read();
bian[m].y=1;
}
for(int i=1;i<=b;i++)
{
bian[++m].u=read();
bian[m].v=read();
bian[m].w=read();
bian[m].y=0;
}
while(q--)
{
x=read();ans=0;k=0;
for(int i=1;i<=m;i++)
if(bian[i].y==1)
bian[i].w+=x;
else if(bian[i].y==0)
bian[i].w-=x;
sort(bian+1,bian+m+1,comp);
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=m;i++)
{
if(gf(bian[i].u)!=gf(bian[i].v))
{
f[gf(bian[i].u)]=bian[i].v;
ans+=bian[i].w;
k++;
}
if(k==n-1)
break;
}
cout<<ans<<endl;
for(int i=1;i<=m;i++)
if(bian[i].y==1)
bian[i].w-=x;
else if(bian[i].y==0)
bian[i].w+=x;
}
return 0;
}


以上。

来自2017.11.6.

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