笔试共有4道编程题,每道题20分,两个小时。这个题感觉比腾讯的简单一点。以下内容的编写全凭记忆和个人理解,如有什么不对的地方,希望大家见谅。
第一题
题意
有一个人用一张1024元的纸币购买价值n元的商品,卖家用四种硬币找零,分别是1、4、16、64,问卖家找零最少需要多少个硬币。
思路
将硬币面值从小到大排序,计算即可。
代码
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>
using namespace std;
int main()
{
int n ;
while(scanf("%d",&n)!=EOF)
{
int rec = 1024 - n;
int num64 = rec / 64;
rec = rec - 64*num64;
int num16 = rec / 16;
rec = rec - 16*num16;
int num4 = rec / 4;
rec = rec - 4*num4;
int num1 = rec / 1;
rec = rec - 1*num1;
printf("%d\n",num64+num16+num4+num1);
}
return 0;
}
第二题
题意
有一个程序员写了个自动处理字符串的代码,规则有两条:①如果有aabb型子串,改为aab;②如果有ccc型子串,改为cc。让我们复现程序员的代码。
思路
模拟题,我的思路是将字符串中不符合规则的位置用字符’@'代替,最后输出的时候忽略这些位置即可。
代码
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>
using namespace std;
char s[8000000];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
int len = strlen(s);
for(int i = 0 ; i < len; )
{
int next1 = i+1;
while(s[next1] == '@' && next1<len)
++next1;
int next2 = next1+1;
while(s[next2] == '@' && next2<len)
++next2;
int next3 = next2+1;
while(s[next3] == '@' && next3<len)
++next3;
if(s[i]==s[next1] && s[next1]==s[next2])
{
s[i] = '@';
i = i+1;
continue;
}
else if(s[i]==s[next1] && s[next2]==s[next3])
{
s[next2] = '@';
continue;
}
else
{
i = i+1;
continue;
}
}
for(int i=0;i<len;++i)
if(s[i]!='@')
printf("%c",s[i]);
printf("\n");
}
return 0;
}
第三题
题意
老师要给一群学生根据他们的成绩发奖品,学生们围在一个圆桌周围,每个人都有自己的成绩。发奖品的规则是:①每个学生都至少有一个奖品;②如果某学生比左右邻座的学生成绩好,那他应收到比他们更多的奖品。问:老师至少需要准备多少个奖品。
思路
按照成绩从小到大排序,依次发奖品即可。这里用到了结构体排序。
代码
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>
using namespace std;
int num[100000+10];
struct TMP
{
int num,ll,rr,rec;
int pos;
}tmp[100000+10],org[100000+10];
int cmp(TMP a, TMP b)
{
return a.num < b.num;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%d",&tmp[i].num);
if(i == 0)
{
tmp[i].ll=n-1;
tmp[i].rr=1;
}
else if(i == n-1)
{
tmp[i].ll=n-2;
tmp[i].rr=0;
}
else
{
tmp[i].ll=i-1;
tmp[i].rr=i+1;
}
tmp[i].rec=1;
tmp[i].pos=i;
org[i].rec = tmp[i].rec;
org[i].ll = tmp[i].ll;
org[i].rr = tmp[i].rr;
org[i].num = tmp[i].num;
}
sort(tmp, tmp+n, cmp);
// for(int i=0; i<n; ++i)
// printf("%d %d %d %d %d\n",tmp[i].pos, tmp[i].num, tmp[i].ll, tmp[i].rr, tmp[i].rec);
for(int i=0; i<n; ++i)
{
int pos = tmp[i].pos;
int should_rec = org[pos].rec;
if(org[pos].num > org[org[pos].ll].num)
should_rec = max(should_rec, org[org[pos].ll].rec+1);
if(org[pos].num > org[org[pos].rr].num)
should_rec = max(should_rec, org[org[pos].rr].rec+1);
org[pos].rec = should_rec;
//printf("%d %d %d %d %d\n",org_pos, tmp[i].num, tmp[i].ll, tmp[i].rr, tmp[i].rec);
}
int ans = 0;
for(int i=0; i<n; ++i)
{
//printf("%d ",org[i].rec);
ans += org[i].rec;
}
printf("%d\n",ans);
}
return 0;
}
第四题
题意
有n根绳子,给出每根的长度。现在要求从这n根绳子中剪出m根等长的绳子(注:不能拼接),问等长绳子最长多长。
思路
等长绳子最短为0,最长肯定不超过n根绳子中最长的绳子长度,所以将左端点设置为0,右短点设置为最长绳长,二分+判断,就可以了。需要注意二分的终止条件那里,精度不能设置的太高,否则会WA,设置成题意中的0.01即可,或者0.001。
代码
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>
using namespace std;
int num[100000+10];
int n,m;
int _check(double _need)
{
int ans = 0;
for(int i=n;i>=1;--i)
{
double tmp = num[i]*1.0;
ans = ans + (tmp/_need);
}
if(ans >= m)
return 1;
else
return 0;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;++i)
scanf("%d",&num[i]);
sort(num+1,num+1+n);
double ll = 0;
double rr = num[n];
while((rr-ll) > 0.001)
{
double mm = (ll+rr)/2;
if(_check(mm))
ll = mm;
else
rr = mm;
}
printf("%.2f\n", ll);
}
return 0;
}