首页 > 代码库 > 杭州的培训Day2考试

杭州的培训Day2考试

简单来说就是完了

思路都对了

就是写不出来

浪费了三个小时来做第一题

还是没有过

然而第三题也没有做对

第二题没空做

这样就...

报零了!

然后第一题:

 

1分糖果

  (candy.pas/c/cpp)

【问题描述】

幼儿园的小朋友要吃糖果,正在幼儿园帮忙的小x接到了这个任务,当然,这个任务不是那么简单。

现在有n名小朋友,m颗糖果,每个小朋友对糖果的需求都不一样,如果知道第i个小朋友需要x[i]颗糖,但是小x必须分给第i个小朋友y[i]颗糖,老师就认为小朋友的不高兴指数为|x[i]/v-y[i]/m|,那么小x的任务就是要保证所有的小朋友不高兴指数最小,也就是要保证

Σ|x[i]/v  y[i]/m|   最小。这里的Σ是求和,||是绝对值。

现在已知n,m,还知道v=Σx[i]。求分配糖果的方案

【输入】

题目包含多组数据,第一行一个整数K,表示K组测试数据

每组测试数据分为两行,第一行三个整数nmv

接下来n个整数,第i个数为x[i]。保证数据合法

 

【输出】

K行,每行输出对应的n个整数,第i个数位所求的y[i]

如果有多组解,你只需输出符合条件的一组即可,有special judge

 

【输入输出样例1

candy.in

candy.out

1

3 10 4

1 1 2

2 3 5

 

 

【数据范围】

  30%的数据中, n、m ≤ 100

 100%的数据中,K ≤ 10, n ≤ 100000

m、v ≤ 10^9, 1 ≤ x[i] ≤ 10000

 

这里给出一个很厉害的P大神的代码

var k,ki,n,m,v,i,me,abme,fme,j,min,dlti,mink,kx:longint;
x,y,dmink,delta,b:array[1..100000]of longint;
yi0R:double;

procedure asson;
begin
assign(input,‘candy.in‘); reset(input);
assign(output,‘candy.out‘); rewrite(output);
end;

procedure assoff;
begin
close(input); close(output);
end;

procedure sort(l,r:longint);
var i,j,mid,temp:longint;
begin
i:=l; j:=r; mid:=delta[(l+r) div 2];
repeat
while (delta[i]<mid) do inc(i);
while (mid<delta[j]) do dec(j);
if (i<=j) then
begin
temp:=delta[i]; delta[i]:=delta[j]; delta[j]:=temp;
temp:=dmink[i]; dmink[i]:=dmink[j]; dmink[j]:=temp;
temp:=b[i]; b[i]:=b[j]; b[j]:=temp;
inc(i); dec(j);
end;
until i>j;
if (l<j) then sort(l,j);
if (i<r) then sort(i,r);
end;

begin
asson;

read(k);
for ki:=1 to k do
begin
read(n,m,v);
for i:=1 to n do read(x[i]);

me:=m;
for i:=1 to n do
begin
yi0R:=x[i]*m/v;
y[i]:=trunc(yi0R);
me:=me-y[i];
end;
while (me<>0) do
begin
abme:=abs(me);
fme:=me div abme;
for i:=1 to n do
begin
min:=maxlongint;
for j:=1 to abme do
begin
if (y[i]+j*fme<0) then break;
dlti:=abs(m*x[i]-v*(y[i]+j*fme))-abs(m*x[i]-v*y[i]);
if (dlti<min) then
begin
min:=dlti;
mink:=j*fme;
end
else break;
end;
delta[i]:=min;
dmink[i]:=mink;
b[i]:=i;
end;
sort(1,n);
for i:=1 to n do
if (me<>0){and(y[b[i]]>0)} then
begin
if (abs(me)>abs(dmink[b[i]])) then kx:=dmink[b[i]]
else kx:=me;
y[b[i]]:=y[b[i]]+kx;
me:=me-kx;
end
else if (me=0) then break;
end;

for i:=1 to n do write(y[i],‘ ‘);
writeln;
end;

assoff;
end.

惨惨的C++:

#include<iostream>
#include<cstdlib>
#include<cstdio>
#Include<string>
using namespace std;
int K,n,m,v,la[10001],jl[],t[10001],x[100001];
int panding(int j){
int u=((la[x[j]])/(t[x[j]]*v));
if(u*v*t[x[j]]>=la[x[j]]){
return u;
}
else{
return u+1;
}
}
int chuli(int maxx){
int laxr=0;
for(int i=1;(i<=maxx)&&(t[i]!=0);i++){
int u=la[i]/(t[i]*v);
char p=u+‘0‘;
int chan=1,mc=0,jh=true;
for(int nowc=la[i]-(u*t[i]*v);jh!=false;){
jh=false;
mc=(t[i]-chan)*u*v+(chan)*(u+1)*v;
if(mc<=nowc){
jh=true;
nowc=mc;
chan++;
}
}

}
}
int main(){
scanf("%d",&K);
for(int i=1;i<=K;i++){
int maxx=0;
scanf("%d %d %d",&n,&m,&v);
for(int j=1;j<=n;j++){
scanf("%d",&x[j]);
maxx=max(maxx,x[j]);
t[x[j]]++;
}
for(int j=1;j<=maxx;j++)
la[j]=j*t[j]*m;
/* for(int j=1;j<=n;j++){
// int gh=(t[x[j]]>1)?((la[x[j]]/(t[x[j]]*v))+1):(((la[x[j]]/v)));
int gh=(panding(j));
cout<<gh<<" ";
la[x[j]]-=gh*(t[x[j]]--)*v;
la[x[j]]=(la[x[j]]>=0)?la[x[j]]:(-la[x[j]]);
}*/
chuli(maxx);
cout<<endl;
}
return 0;
}

 

然后是第二题:

没时间做啊

题目是这样的:

2文艺诗人

  (poet.pas/c/cpp)

【问题描述】

写诗是每个文艺青年必须要有的技能,小x也不例外。

x收集到了很多诗句,并且按照平仄韵律排好相应的顺序,根据经验,他可以在这些诗句中连续一些句子组成自己想要的诗,当然,他可以组成很多很多诗。

每个诗句都有两个属性,长度和文艺值,现在小xn个诗句可以挑选来组诗。一首诗的长度就是组成这首诗的每个句子的长度之和,一首诗的文艺值也是每个句子的文艺值之和。

为了保证组成的诗的整体性和美观性,小x对组诗有以下要求:

1) 挑选诗句必须按照给定的先后顺序挑选,不能调换顺序,同一首诗,必须要在诗句中连续的挑选,数量不限。

2) 一首诗的总长度不能低于一个值low,也不能超过一个值high。诗的总长度是每个诗句的长度之和。

3) 不允许出现两首诗,一首诗所有的语句出现在另一首诗中,也就是说不能出现两首诗是包含与被包含关系。

4) 一个句子可以出现在多首诗中。

现在小x想知道,在满足以上条件的基础上,可以组成的所有诗的最大文艺值是多少

 

【输入】

第一行,三个整数nlowhigh

第二行有N个整数,第i个整数l[i]表示第i句诗句的长度值

第三行有N个整数,第i个整数w[i]表示第i句诗句的文艺值。

【输出】

一个整数S,表示所求的组成所有诗的最大文艺值

 

【输入输出样例1

poet.in

poet.out

6 4 5

1 3 3 2 2 1

2 3 1 4 5 2

21

[1,2]的文艺值为5  [3,4]的文艺值为5    [4,6]的文艺值为11  合计文艺值为21

 

【数据范围】

    对于40%的数据,1 <= n <= 100;

对于100%的数据,1 <=n <= 1000;

单个句子的长度和文艺值都小等于100000;

其余给出的均在int范围内。

 

代码嘛,没有没有

 

 

 

第三题:

3唯一生成树

  (tree.pas/c/cpp)

【问题描述】

x对生成树很有研究,他很早就发现,一个图的最小生成树并不是唯一的,有一道题目是求次小生成树,当然小x不会让你求。

x首先画了一颗树,并且他认为这就是某个图的最小生成树,现在他要将这颗树里再加入其它的边,将这个树补成一个完全图,但是要让这颗生成树是这个完全图的唯一最小生成树。

当然,随便的加边肯定可以完成,小x想知道保证最小生成树的基础上,使得补好的完全图的权值累加和最小。

现在小x把问题交给了你,如果能把这个问题解决,你今年的rp会得到很大的增强。

【输入】

此题有多组数据,第一行一个整数M,表示有M组数据。

每组数据第一行一个整数n,表示这颗树有那个节点

接下来有n-1行,每行3个整数 uvw,表示点u和点v之间有一条权值为w的边。

【输出】

M行,每行一个整数,表示构成完全图的权值之和。

 

【输入输出样例1

tree.in

tree.out

1

3

1 2 4

2 3 7

19

 

【数据范围】

  30%的数据中, n ≤ 1000

100%的数据中,M≤ 20, 1 ≤ n ≤ 15000

1 ≤ u、v ≤ n, w ≤ 10000

保证数据合法

 

 

代码嘛:

不太完美的一个C++

还请各位大神完善一下

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<string>
using namespace std;
int m,n,zx=-1,MST=0;
void zse()
{
cin>>n;
int a[n+1][n+1];
bool chao[n+1];
int zxxxx[n+1];
chao[1]=1;
memset(chao,0,sizeof(chao));
memset(a,-1,sizeof(a));
memset(zxxxx,99999999,sizeof(zxxxx));
for(int i=1;i<=n-1;i++)
{
a[i][i]=99999999;
int ll,rr,ee;
cin>>ll>>rr>>ee;
a[ll][rr]=a[rr][ll]=ee;
}
zxxxx[1]=0;
a[n][n]=99999999;
for(int i=1;i<=n;i++)
{
if(a[1][i]!=-1)
{
zxxxx[i]=a[1][i];
}
else
{
zxxxx[i]=99999999;
}
}//潮吧!把数据挪移
for(int i=1;i<=n;i++)
{
int k=0;
zxxxx[0]=99999999;
for(int qwe=1;qwe<=n;qwe++)
if(!chao[qwe]&&(zxxxx[qwe]<zxxxx[k]))
k=qwe;
chao[k]=1;
for(int qwe=2;qwe<=n;qwe++)
if(!chao[qwe]&&a[k][qwe]<zxxxx[qwe])
zxxxx[qwe]=a[k][qwe];

}
for(int i=2;i<=n;i++)
{
MST+=zxxxx[i];
if(zxxxx[i]>zx)
zx=zxxxx[i];
}
zx=zx+1;
int ask=0;

for(int qwe=1;qwe<=n;qwe++)
for(int i=1;i<=n;i++)
if(a[i][qwe]==-1)
ask++;//bulianjiedediandegeshu
ask=ask/2;
MST+=ask*zx;
cout<<MST;
return;
}


int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
cin>>m;
for(int i=1;i<=m;i++)
zse();
return 0;
}

杭州的培训Day2考试