@[TOC] 石家庄铁道大学新生选拔赛
蒲煜凡教女生算法
蒲煜凡送花
蒲煜凡的约会
蒲煜凡与徐利峰大魔王
甘靖的普通话
蒲煜凡教女生算法
题目描述
迷人的蒲煜凡学长总是能吸引很多漂亮的小学妹前来请教算法问题,可是蒲煜凡最近正在学习编译原理,实在是太忙了,因此只能把所有前来请教的学妹约到一段时间一起讲解。
为了避免让小学妹们等急,他想让所有来请教的学妹们等待的时间最少,因此他利用自己发明的算法对每个学妹进行了分析,根据她们的每个人的聪慧程度计算出所需要讲解的时间。
但是,他还是不清楚怎么安排能达到这个目的与学妹们一共需要等待的时间,聪明的你能帮助他吗?
输入描述:
第一行一个整数n
第二行包含n个整数,其中第i个整数表示第i个人需要讲解的时间,如果a[i]<=0表示她只是想见蒲煜凡学长一面不需要进行讲解。
备注:
1≤n≤1e5(人数)
1≤ai≤1e4(需要讲解的时间)
输出描述:
输出最小等待时间
输入
9
3 6 1 4 2 5 7 0 -1
输出
56
思路,,这道题就是先给用时短的讲(排序),忽略<=0的部分,注意是等待时间,所以是(总人数减一)*用时
具体见代码
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int a[maxn];
int main()
{
long int n,t,sum=0;
scanf("%ld",&n);
for(long int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);//从小到大找到最小的,
t=n;
for(long int i=1;i<=n;i++)
{
if(a[i]<=0) //忽略小于0的,人数也要减
t--;
else
{
sum+=a[i]*(t-1);
t--;
}
}
printf("%ld",sum);
}
蒲煜凡送花
题目描述
蒲煜凡学长最近迷上了一个漂亮的小学妹,他想送一朵特别的花给这个小学妹。
他现在有一把N朵漂亮的花,每多花都有a[i]个花瓣,如果有1朵花的花瓣数与其他任意一朵花的花瓣数之差等于2,那么他可以选择把这朵花扔掉,也可以选择丢弃。
请问经过若干次操作之后蒲煜凡学学长能找到唯一的一支特别的花送给小学妹吗?
输入描述:
第一行一个整数t(1<=t<=500)表示测试样例数
每个测试样例第一行一个整数n(1<=n<=1e4)表示花的数量,第二行n个整数ai表示花瓣数。
输出描述:
输出t行"YES"or"NO"
示例1
输入
1
4
2 4 6 8
输出
YES
示例2
输入
1
5
9 3 5 6 7
输出
NO
思路,,这个两数之间只能相差2或0才能过,所以为了省事,就去重做,222222,这样的情况过不了,单独来算。(2244,224,244,24都YES)
具体见代码
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
const int M=1e8;
long long int a[M],c[M];
map<long long,long long>mp;
int main()
{
int t,l=0;
long int n,s,q=0;
scanf("%d",&t);
while(t--)
{
mp.clear();
scanf("%ld",&n);
s=n;
for(long int i=0;i<n;i++)
{
scanf("%lld",&a[i]);
//去重
mp[a[i]]++;
//cout<<mp[a[i]];
if(mp[a[i]]==1)
{ //s=s-mp[a[i]-2]
c[q]=a[i];
q++;
}
if(mp[a[i]]>1)
s--;
}
sort(c,c+s);
for(long int i=0;i<s-1;i++)
{
if(c[i]!=c[i+1]-2)
{
printf("NO\n");
l++;
break;
}
}
if(n==1)
{
printf("YES\n");
continue;//显而易见的
}
if(s==1)printf("NO\n");
if(l==0&&s!=1)
{
printf("YES\n");
}
}
}
蒲煜凡的约会
链接:https://ac.nowcoder.com/acm/contest/9564/E
来源:牛客网
题目描述
蒲煜凡学长跟学妹出来约会了!蒲煜凡学长作为一名标准直男,想要给学妹买一杯奶茶,便问学妹喜欢喝什么样的奶茶,学妹回了两个字
随便!
蒲煜凡学长傻眼了,但作为一名优秀的ACMer,他是不会坐以待毙的,他早早便将学妹喜欢喝的奶茶价格和奶茶店的价格表弄到了手!现在你要根据奶茶价格,判断学妹到底喜欢喝哪一种奶茶,如果有多种奶茶价格都符合要求,输入种类靠前的一种
输入描述:
第一行包含一个整数n,表示有n种奶茶
第二行有n个数字a[i],a[i]表示第i种奶茶价格
第三行包含一个整数Q,表示Q次询问
第四行包含Q个整数x[i],表示学妹喜欢喝的第i杯奶茶的价格,如果没有找到,则输出-1
备注:
1 ≤ Q ≤ 1e5, 1≤ n≤ 1e6
奶茶价格都在int范围内~
输出描述:
输出Q行,每行一个整数表示答案
示例1
输入
6
1 2 10 5 3 2
1
3
输出
5
示例2
输入
5
3 1 7 5 8
2
6
7
输出
-1
3
思路 这道题按照一般情况直接查会超时,可以采用,标记原位置,对价格排序,然后找到价格输出标记的位置
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e6+10;
long int b,q,s;
struct naicha
{
long long int m,n;
}ss[maxn];
//采用结构体进行标记位置
bool cmp(naicha A,naicha B){
return A.m<B.m||A.m==B.m&&A.n<B.n;//多个限制条件,不加不过
}
int main()
{
scanf("%ld",&b);
for(long int i=1;i<=b;i++)
{
scanf("%lld",&ss[i].m);
ss[i].n=i;
}
sort(ss+1,ss+b+1,cmp);
scanf("%ld",&q);
for(long int j=0;j<q;j++)
{
scanf("%ld",&s);
//二分
long long int l=1,r=b,mid;
while(l<r)
{
mid=(r+l)/2;
if(ss[mid].m>=s) r=mid;
else l=mid+1;
}
if(ss[l].m==s)
cout<<ss[l].n<<endl;
else
cout<<"-1"<<endl;
}
}
蒲煜凡与徐利峰大魔王
链接:https://ac.nowcoder.com/acm/contest/9564/F
来源:牛客网
题目描述
徐利峰大魔王抢走了蒲煜凡学长刚交的npy,回到了自己的王国,为了npy,蒲煜凡学长是不会善罢甘休的,恰巧蒲煜凡学长刚学会了影分身之术,他决定打败徐利峰大魔王,夺回npy,不过蒲煜凡学长的影分身之术还不太熟练,他不知道自己要变幻出多少个影分身才能确保一定能找到徐利峰大魔王
徐利峰大魔王的王国错综复杂,已知王国中有n个的城市,m条通路(无向边),为了蒲煜凡学长的未来,请你编写一个程序确定他的分身数目。
输入描述:
第一行城市数量n(1<=n<=1e5),通路的条数m(0<=m<=1e5),城市中可能有重边和自环
下面m行每行包含两个整数x和y,表示x和y之间存在一条通道
输出描述:
输出最少需要多少个影分身
输入
5 4
1 4
2 4
4 2
2 2
输出
3
这个用并查集做,找到一个father,就减一
#include<iostream>
using namespace std;
const int maxn=1e5+5;
int father[maxn];
long int find(long int x)
{
if(father[x]!=x)
father[x]=find(father[x]);
return father[x];
}
int main()
{
long int n,m;
cin>>n>>m;
for(long int i=1;i<=n;i++)
{
father[i]=i;
}
long int ans=0;
while(m--)
{
long int a,b;
cin>>a>>b;
int fa=find(a);
int fb=find(b);
if(fa!=fb)
{
father[fa]=fb;
n--;
}
}
cout<<n;
}
链接:https://ac.nowcoder.com/acm/contest/9564/G
来源:牛客网
题目描述
大多数情况下甘靖学长说普通话时都很标准,但有时却令人抓狂,这件事困扰他很久了,突然有一天,他想通过读数字来纠正他的发音,
但是他不想按正常的顺序读数字,于是他按照某种规律写了一些数字在黑板上,比如如果他想数到9,那么他会把数字写成如下格式:
1 2 6 7
3 5 8
4 9
如果他想数到15,那么他会把数字写成如下格式:
1 2 6 7 15
3 5 8 14
4 9 13
10 12
11
他突然发现他写数字的规律是个蛇形,具体描述是这样的:
对于每一条左下-右上的斜线,从左上到右下依次编号1,2,…,2n-1;按编号从小到大的顺序,将数字从小到大填入各条斜线,其中编号为奇数的从左下向右上填写,编号为偶数的从右上到左下填写
输入描述:
输入一个不大于10000的正整数n,表示要填充到的数字的大小
输出描述:
按规律输出这些数字,相邻两个元素之间用单个空格间隔
输入
50
输出
1 2 6 7 15 16 28 29 45 46
3 5 8 14 17 27 30 44 47
4 9 13 18 26 31 43 48
10 12 19 25 32 42 49
11 20 24 33 41 50
21 23 34 40
22 35 39
36 38
37
思路:这道题要发现是斜着排的。i+j是定值,就可以以这个规律去赋值
#include<iostream>
#include<cstdio>
#include<cmath>
int a[10000][10000];
using namespace std;
int main()
{
int n,m,l=0,t=0;
cin>>n;
m=(int)sqrt((double)n*2);//用这个方式确定边界
for(int j=1;j<=m+1;j++)
{
for(int i=1;i<=j;i++)
{
t++;
if(t>n) break;
//斜着排时跟奇偶有关
if(j%2==0)
a[i][j-i+1]=t;
else
a[j-i+1][i]=t;
}
}
for(int j=1;j<=m+1;j++)
{
for(int i=1;i<=m+1;i++)
{
if(a[j][i]==0)
break;
cout<<a[j][i]<<" ";
}
printf("\n");
}
}