笔试共有3道编程题,分别为100分、200分、300分,两个小时。以下内容的编写全凭记忆和个人理解,如有什么不对的地方,希望大家见谅。
第一题
题意
给出一个字符串,由许多子串组成,每个子串长度都是9,如果子串的第一位是0,就将该子串反序输出,如果子串的第一位是1,就将该子串正序输出。
思路
没啥说的,签到题,暴力就ok,可是我代码写的太丑了。。。
代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<stack>
using namespace std;
char s[500];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
scanf("%s",s);
int len = strlen(s);
s[len]='1';
len++;
int start = 1;
int end = 1;
int rev = 0;
int flag = 0;
int str_num = 0;
for(int i=0;i<len;)
{
if(s[i] == '0')
{
if(flag == 0)
{
rev = 1;
flag = 1;
start = i+1;
i=i+9;
}
else
{
flag = 0;
end = i-1;
if(str_num == 0)
str_num = 1;
else
printf(" ");
if(rev == 1)
{
for(int j = end; j>=start; --j)
printf("%c",s[j]);
}
else
{
for(int j = start; j<=end; ++j)
printf("%c",s[j]);
}
}
}
else if(s[i] == '1')
{
if(flag == 0)
{
rev = 0;
flag = 1;
start = i+1;
i=i+9;
}
else
{
flag = 0;
end = i-1;
if(str_num == 0)
str_num = 1;
else
printf(" ");
if(rev == 1)
{
for(int j = end; j>=start; --j)
printf("%c",s[j]);
}
else
{
for(int j = start; j<=end; ++j)
printf("%c",s[j]);
}
}
}
else
++i;
}
printf("\n");
}
return 0;
}
第二题
题意
一个蜜蜂,最开始在原点,要去五个其他位置采蜜,求采完回到原点的最短路径。
思路
我写了一个特别丑的暴力,真的不能再丑了。觉得写一个全排列或者搜索能好看一点。需要注意的是最后输出的时候,要把答案减0.5,因为.0lf会四舍五入,而题中要求截断小数部分。
代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<stack>
using namespace std;
double x[10],y[10];
double edge[10][10];
double calc_dis(double x1,double y1,double x2,double y2)
{
double tmp1 = (x1-x2)*(x1-x2);
double tmp2 = (y1-y2)*(y1-y2);
return sqrt(tmp1+tmp2);
}
int main()
{
while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",&x[1],&y[1],&x[2],&y[2],&x[3],&y[3],&x[4],&y[4],&x[5],&y[5])!=EOF)
{
x[0]=y[0]=0;
for(int i=0;i<=5;++i)
for(int j=0;j<=5;++j)
edge[i][j]=edge[j][i]=calc_dis(x[i],y[i],x[j],y[j]);
double ans = 99999999999;
for(int i=1; i<=5; ++i)
for(int j=1; j<=5; ++j)
for(int k=1; k<=5; ++k)
for(int l=1; l<=5; ++l)
for(int p=1; p<=5; ++p)
{
if(i==j || i==k || i==l || i==p ||
j==k || j==l || j==p ||
k==l || k==p ||
l==p)
continue;
double tmp = edge[0][i] + edge[i][j] + edge[j][k] + edge[k][l] + edge[l][p] +edge[0][p];
ans = min(ans, tmp);
}
printf("%.0lf\n",ans-0.5);
}
return 0;
}
第三题
题意
有个网格,在某些格子上有水果,我们可以横、竖、对角(2种)切水果,问最少几刀可以把水果切没。
思路
我觉得是搜索,然后写啊写,到最后结束了知道’\\\'是续行符,我有一行代码由于自己写了注释,咋都运行不了,我都蒙了。我的搜索太丑了,可以再优雅点,有些地方也能记忆化一下,我也不知道会不会TLE,会不会WA,1个半小时都在调试。。。
代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<stack>
using namespace std;
int x[60],y[60];
int vis[60];
int vis_num;
int max_n=40;
int max_m=50;
int n;
int end_ans;
int calc_cut(int start, int style)
{
printf("start:%d %d style=%d\n",x[start],y[start],style);
int ans=0;
if(style == 1)
{
for(int i=1;i<=n;++i)
if(x[i]==x[start] && vis[i]==0)
ans++;
}
if(style == 2)
{
for(int i=1;i<=n;++i)
if(y[i]==y[start] && vis[i]==0)
ans++;
}
if(style == 3)
{
for(int i=1;i<=n;++i)
{
if((x[i]-x[start])==(y[i]-y[start]) && vis[i]==0)
{
ans++;
//printf("i=%d %d %d\n",i,x[i],y[i]);
}
}
}
if(style == 4)
{
//cout<<"---------"<<endl;
for(int i=1;i<=n;++i)
if((x[i]-x[start])==(y[start]-y[i]) && vis[i]==0)
{
ans++;
//printf("i=%d %d %d\n",i,x[i],y[i]);
}
}
return ans;
}
int cut[10];
void dfs(int start, int vis_num, int cut_times)
{
if(vis_num >= n)
return ;
printf("----------------------------\n");
cut[1] = calc_cut(start,1);// ---
cut[2] = calc_cut(start,2);// |||
cut[3] = calc_cut(start,3);// \\\
cut[4] = calc_cut(start,4);//
int max_cut=cut[1];
int max_i=1;
for(int i=1;i<=4;++i)
if(cut[i]>max_cut)
{
max_cut=cut[i];
max_i=i;
}
//printf("start=%d max_cut=%d cut_i=%d cut_times=%d vis_num=%d\n",start,max_cut,max_i,cut_times,vis_num);
//printf("%d %d %d %d\n\n\n",cut[1],cut[2],cut[3],cut[4]);
//printf("%d\n",max_i);
if(max_i == 1)
{
int next;
for(int i=1;i<=n;++i)
if(x[i]==x[start] && vis[i]==0)
{
vis[i]=1;
vis_num++;
}
else
next=i;
if(vis_num == n)
end_ans = min(end_ans, cut_times);
else
dfs(next, vis_num, cut_times+1);
}
if(max_i == 2)
{
int next;
for(int i=1;i<=n;++i)
if(y[i]==y[start] && vis[i]==0)
{
vis[i]=1;
vis_num++;
}
else
next=i;
if(vis_num == n)
end_ans = min(end_ans, cut_times);
else
dfs(next, vis_num, cut_times+1);
}
if(max_i == 3)
{
int next;
for(int i=1;i<=n;++i)
if((x[i]-x[start])==(y[i]-y[start]) && vis[i]==0)
{
vis[i]=1;
vis_num++;
}
else
next=i;
if(vis_num == n)
end_ans = min(end_ans, cut_times);
else
dfs(next, vis_num, cut_times+1);
}
if(max_i == 4)
{
//printf("--------------------\n");
int next;
for(int i=1;i<=n;++i)
if((x[i]-x[start])==(y[start]-y[i]) && vis[i]==0)
{
vis[i]=1;
vis_num++;
}
else
next=i;
if(vis_num == n)
end_ans = min(end_ans, cut_times);
else
dfs(next, vis_num, cut_times+1);
}
return ;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;++i)
scanf("%d%d",&x[i],&y[i]);
memset(vis,0,sizeof(vis));
end_ans=1234567890;
dfs(1, 0, 1);
printf("%d\n", end_ans);
}
return 0;
}