Tyvj2017清北冬令营入学测试

时间:2022-12-31 16:05:26
 

 

 

 

 

P4744 A’s problem(a)

时间: 1000ms / 空间: 655360KiB / Java类名: Main

背景

冬令营入学测试题,每三天结算一次成绩。参与享优惠

描述

这是一道有背景的题目,小A也是一个有故事的人。但可惜的是这里纸张太小,小A无法把故事详细地说给大家听。可能小A自己也讲不清楚自己的故事,因为如果讲清了,也就没有这道题目了……

小A的问题是这个样子,它找到了n份不同的工作,第i份工作每个月有ai的工资,每份工作需要小A每天工作8小时,一周工作7天。小A想知道性价比最高(一个月的工资除以总时长)的工作的编号是多少。如果有多份,输出编号最小的就可以了。

输入格式

第一行一个数n,表示有n份工作。

         接下来n个数表示ai。

输出格式

输出一个数表示答案。

备注

输入样例

5

3 3 4 5 5

 

输出样例

4

 

数据范围

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

 【水题不多说系列】

#include<iostream>
using namespace std;
int n,a[110];
int main()
{
cin
>>n;
for(int i=1;i<=n;i++)
cin
>>a[i];
int j=1;
for(int i=2;i<=n;i++)
if(a[i]>a[j])j=i;
cout
<<j;
return 0;
}

P4745 B’s problem(b)

时间: 1000ms / 空间: 655360KiB / Java类名: Main

背景

冬令营入学测试

描述

题目描述

         小B生活在一个很奇怪的国家里,这个国家的钱的面值只有可能是25,50,100的。小B最近在做社会实践,这次它选择在一个餐厅里干这件事情。但今天发生了一件有趣的事,这件事情是这个样子的,餐厅里大家都在排队买饭,粗心的打饭阿姨忘记要带零钱,并且所有排队打饭的人只带了一张钱。

         具体地,第i个人带了一张面额为ai的钱,为了方便起见,我们规定每个人都想买价值25元的饭盒。阿姨显得不知所措。聪明的小B想到了一个方法,让带了25元的先买饭!这样阿姨就有了更多的零钱去找开一些面值较大的钱。

         但这样对于一些人来说仍有可能找不开零钱,小B想知道是否存在一种排队方案,能够对所有人找开零钱。如果可行输出“YES”,否则输出“NO”。

输入格式

第一行一个数n,表示有n个想买饭的人。

         接下来一行n个数ai,表示第i个人带着的钱的面额。

 

输出格式

输出“YES”或者“NO”。

 

备注

输入样例

3

25 50 100

 

输出样例

NO

 

数据范围

对于100%的数据n<=100,ai=25或者50或者100。

 思路

把所有的人拿的钱从小到大排个序,另外可以发现

如果这个人拿的是25元,那么不需要找钱,我的钱包里就多了25元

如果这个人拿的是50元,那么只有一种解决办法,用一张25元的和他换,如果此时我没有25元的那么“NO”(因为我已经把人们从大到小排过序了,所以后面的人不可能有25的钱)

如果这个人拿的是100元,有两种办法

  用一张50和一张25与他换,要求b25>=1,b50>=1

  用三张25与他换,要求b25>=3

不满足要求则NO

#include<iostream>
#include
<algorithm>
using namespace std;
int n,a[110],b25,b50,b100;
bool flag;
int main()
{
cin
>>n;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a
+1,a+n+1);
for(int i=1;i<=n;i++)
{
if(a[i]==25)b25++;
if(a[i]==50)
{
if(b25==0)flag=1;
else b25--,b50++;
}
if(a[i]==100)
{
if(b25==0)flag=1;
else{
if(b25>=1&&b50>=1){
b25
--;b50--;
continue;
}
else if(b25>=3){
b25
-=3;
continue;
}
else flag=1;
}
}
}
if(flag==0)cout<<"YES";
else cout<<"NO";
return 0;
}

 

P4747 D’s problem(d)

时间: 1000ms / 空间: 655360KiB / Java类名: Main

背景

冬令营入学测试题

描述

题目描述

         小D是一名魔法师,它最喜欢干的事就是对批判记者了。

         这次记者招待会上,记者对于小D的数学很好奇。于是小D找了个方法把记者批判了一番。

         它对记者抛出了这么一个问题:我有n点能量,写下数字i(1<=i<=9)需要花费a{i}点能量,我用这n点能量最多能写出什么数来?(当然可以不用光n点能量,具体看样例)

         记者们一脸懵逼,于是来求助于你。

输入格式

一行10个数,表示n,a1,a2,a3,…,a9。

输出格式

一个数表示答案。

备注

输入样例1

10 2 2 1 2 2 2 2 2 2

 

输出样例1

3333333333

 

输入样例2

10 4 11 11 11 11 11 11 11 10

 

输出样例2

11    

 

数据范围

对于30%的数据n,ai<=10。

对于60%的数据n,ai<=100。

对于100% 的数据1<=n,ai<=1000000,n>=min{ai}。

思路

输出的数最大,首先要保证输出的位数最大,其次要尽量使高位上的数值最大

找到数列中的最小值,即可找到输出的最大位数=总能量/最小值

可能在输出一串最小值代表的位置后发现还有能量剩余,那么这些能量不用白不用,但是我们输出的数字已经是用能量最小的数字了,没有更小的供我单独利用剩余能量了,于是我只能试图去最初确定的数列中改变一些数,当然,为了不越改越小,我们要从9倒着循环,到最小值就结束。

关于实现,我们只需要一次一次的加进余数,然后在计算中获得新的余数,我在代码中说的比较清楚

#include<cstdio>
#include
<iostream>
#include
<algorithm>
using namespace std;
int n,t;
int a[2000000];
int min1=99999999;
int flag=1;
int main()
{
cin
>>n;
for(int i=1;i<=9;i++)cin>>a[i];
for(int i=9;i>=1;i--)
{
if(a[i]<min1)
{
min1
=a[i];//找到最小数的大小min1和序号t
t=i;
}
}
int s=n/a[t];//最多可以输出s个t
int q=n%a[t];//输出s个t后,还剩q个能量
int p=0;
for(int j=1;j<=s;j++)
{
q
+=min1;//剩下的能量加上输出这个位置上的t所需要的能量,可能得到更优的解,933总比333优吧,那就把输出333剩下的能量分配出一点来供给输出9,还得保证输出数字的位数不变
for(int i=9;i>=t;i--)//从9到t中寻找更划算
if(a[i]<=q)
{
q
=q-a[i];//我又计算出一个新的剩余能量
cout<<i;
p
++;//p代表了被我修改(用剩余能量补偿至>t)的数的个数
}
}
for(int i=1;i<=s-p;i++)cout<<t;//把未经修改的位置上填满t
return 0;
}

 

P4749 F’s problem(f)

时间: 1000ms / 空间: 655360KiB / Java类名: Main

背景

冬令营入学测试

描述

这个故事是关于小F的,它有一个怎么样的故事呢。

         小F是一个田径爱好者,这天它们城市里正在举办马拉松比赛,这个城市可以被看作是n个点m条带权有向边组成的图。马拉松比赛的终点只有一个:点S。

         有k个人参加了这场马拉松,小F所在的城市的马拉松与正常的马拉松不一样,每个人的起点都是不相同的,具体地,第i个人从第{ai}个城市出发,并且第i个人的速度是{vi}。每个人当然是会沿着最短路跑到S点,如果一个人跑步的距离是s,速度是v,那么他所花费的时间为s/v。

         现在小F想知道,谁是最快到达终点的。若有多个同时到达终点的,就求跑的路最长的,如果有多个同时到达终点且跑的路最长的,就求编号最大的。

         小F想知道那个人的编号是多少。

 

输入格式

第一行3个数字,n,k,m,表示点的个数,跑步的人数,以及路径的条数。

         接下来一行m行,每行3个数ai,bi,ci表示有一条从ai到bi长为ci的有向路径。

         接下来一行一个数S。

         接下来一行k个数,表示每个人的起点xi。

         接下来一行k个数,表示每个人的速度vi。

输出格式

输出一个数表示答案。

 

测试样例1

输入

5 2 10 
5 1 9 
1 2 81 
2 3 30 
2 1 46 
1 4 45 
2 4 48 
5 1 93 
2 5 61 
2 5 21 
3 5 45 

3 5 
18 29

输出

2

备注

输入样例

3 2 3

1 2 2

1 3 3

2 3 1

3

2 1

1 3

 

输出样例

2

 

数据范围

对于30%的数据n<=5,m<=10。

对于100%的数据n<=300,m<=5000。0<=ci<=100,1<=xi,S<=n,1<=vi<=100,1<=k<=n。

 思路

数据范围好xiao,本少大放心头之快,写了一篇弗洛伊德

弗洛伊德求出最短路。then balabala……(都在代码中了)

#include<iostream>
using namespace std;
int a[301][301];
int n,k,m,s;
int x,y,z;
int xi[301],vi[301];
double minx=999999;
int jl,jlk;
int main()
{
cin
>>n>>k>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(a[i][j]==0&&i!=j) a[i][j]=999999;
for(int i=1;i<=m;i++)
{
cin
>>x>>y>>z;
a[x][y]
=z;
}
for(int kk=1;kk<=n;kk++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i!=j&&i!=kk&&j!=kk)
{
a[i][j]
=min(a[i][j],a[i][kk]+a[kk][j]);
}
}
cin
>>s;
for(int i=1;i<=k;i++)
cin
>>xi[i];
for(int i=1;i<=k;i++)
cin
>>vi[i];
for(int i=1;i<=k;i++)
{
if(a[xi[i]][s]*1.0/vi[i]<=minx)
{
if(a[xi[i]][s]*1.0/vi[i]==minx)
{
if(a[xi[i]][s]>=a[jlk][s])
{
minx
=a[xi[i]][s]*1.0/vi[i];
jl
=i;
jlk
=xi[i];
}
}
else{
minx
=a[xi[i]][s]*1.0/vi[i];
jl
=i;
jlk
=xi[i];
}
}
}
cout
<<jl;
}