【test】2015.7.31测试解题报告(一)

来源:互联网 发布:淘宝怎么直播呀 编辑:程序博客网 时间:2024/06/06 17:24

每天都要测试的赶脚真不好啊╮(╯﹏╰)╭,好吧,昨天下午和今天是综合的测试,明天就要来一次大测了~~~~还好可以回家~~~~。今天的题目难度有些是水题,当然也有难的,还有需要进行算法分析优化的……总之就看接下来的报告吧……(然并卵)

 

(以下由我认为从易到难排列)

 

 

一、Talk

问题描述:

FJ发现一个有趣的事实.当他的牛说话时,总有一些字母用得比其他字母多.给出一些奶牛说的话,请计算出用得最多的5个字母.

输入将有5行,每行由不多于80个字母A~Z和空格组成.

你要输出出现最多的5个字母,按出现次数由多到少排序,由空格分隔.如果少于5个字母出现,则有多少出现就输出多少.如果两个字母出现次数一样多,按字母表先后顺序输出.

 

输入:

 

MOO

MOO

MOO

MOO

WHY IS EVERYBODY MOOING NOW

 

 

输出:

O M Y E I

 

 

样例解释:

O用了12次,M用了5次,Y用了3次,E用了2次,I也用了2次(N和W同样用了2次,但按字母表先后顺序,所以只取了E和I).

 

【问题分析】

纯粹的水题,应该不算是什么难题吧~就是输入五行的字符串,把每个字符取出来,然后sort排序一下。当然需要注意的是如果出现的字母不足五个只用输出有的字母,容易被坑。

 

【例程】

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

string st;

struct Talk
{
int n;
char ch;
};
Talk cow[27];

int cmp(Talk a,Talk b)
{
if(a.n==b.n)
return a.ch<b.ch;
return a.n>b.n;
}

int main()
{
freopen("talk.in","r",stdin);
freopen("talk.out","w",stdout);

for(int i=0;i<26;++i)
cow[i].ch=char(i+'A');

for(int i=0;i<5;++i)
{
getline(cin,st);
int len=st.length();
{
for(int j=0;j<len;++j)
if(st[j]>='A'&&st[j]<='Z')
cow[st[j]-'A'].n++;
}
}

sort(cow+0,cow+26,cmp);

for(int i=0;i<5;++i)
{
if(cow[i].n>0)
cout<<cow[i].ch<<" ";
else
break;
}
return 0;
}


二、 Usaico

Problem XX: USAICO [Russ Cox, 2006]

 

FJ的农场举行了异一场USA奶牛奥林匹克竞赛.N(1<= N <= 100,000; N 是一个奇数)只奶牛都已经获得了一个整数分数S(0 <= S <= 10,000).

 

FJ必须统计这些分数以便指导他们.帮帮他吧~~给出一个列表,计算最小值、最大值、中间数、众数。中间值是一个值M,至少一半的数<=M,至少一半的数>=M。众数是指出现次数最多的一个数。FJ知道分数里面只有一个众数。

 

 

 

PROBLEM NAME: usaico

 

INPUT FORMAT:

*1行:一个整数N

 

*2..N+1行:每一行有一个整数,是一只奶牛的分数

 

 

SAMPLE INPUT (file usaico.in):

 

9

1

3

15

3

5

6

7

8

3

 

INPUT DETAILS:

9只奶牛的分数,在115之间

 

OUTPUT FORMAT:

*1行:四个用空格隔开的整数:最小值、最大值、中间数、众数

 

SAMPLE OUTPUT (file usaico.out):

 

1 15 5 3

 

OUTPUT DETAILS:

 

最小值是 1;最大值是 15;中间值是 5;众数是 3,出现了3

 

【问题分析】

这题数据范围较小,只有10w,所以先sort排序一下,最小、最大、中间直接就可以取出来,众数再用强搜的方法求出来就可以,不难。

【例程】

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int n,s[10000002];
int jl,modei;

int main()
{
freopen("usaico.in","r",stdin);
freopen("usaico.out","w",stdout);

scanf("%d",&n);
for(int i=0;i<n;++i)
scanf("%d",&s[i]);

sort(s+0,s+n);

jl=s[0];
int lon=1,alon=1;
modei=0;
for(int i=1;i<n;++i)
{
if(s[i]==jl)
++lon;
else
{
jl=s[i];
if(lon>alon)
{
alon=lon;
modei=i-1;
}
lon=1;
}
}
if(lon>alon)
{
alon=lon;
modei=n-1;
}

printf("%d %d %d %d\n",s[0],s[n-1],s[n/2],s[modei]);
return 0;
}



三、frisbee

问题描述:

   输入P (0 <= P <= 2,000,000,000) Q(1 <= Q <= 2,000,000,000) ,

   输出 P除以Q 并且 截尾(取整),不准用”div”命令.

输入

  7 2

输出

  3

 

说明:

  7/2=3.5  取整后得3


【问题分析】

    【问题分析】

这题就是除法,只是不允许使用div(即c++的直接除)。这里要提出一个运用二进制求结果的方法。本来是想放后几题,但鉴于难度不大,只用理解就放这里了。(可能会讲得不清楚)

 

大家都知道电脑是用二进制表示的,像原题中的72,化成二进制就是:

【test】2015.7.31测试解题报告(一) - 李kuandui - 神殇KD灬度阡陌

 所以,我们可以采用位运算的方法,将2的二进制向左移n位,直到再移一位就会大于现在的被除数(即7)为止,此时ans就加上n,将被除数减去这个数。就这样依次类推,得到结果为3.

【test】2015.7.31测试解题报告(一) - 李kuandui - 神殇KD灬度阡陌

当然也可以反向来做,即把被除数向右移,处理方法类似,自己体悟!

【例程】

#include<iostream>
#include<cstdio>
using namespace std;

long long a,b,ans=0;

int main()
{
freopen("frisbee.in","r",stdin);
freopen("frisbee.out","w",stdout);

cin>>a>>b;

for(int i=30;i>=0;--i)
{
if((a>>i)>=b)
{
ans+=(1<<i);
a-=(b<<i);
}
}

cout<<ans<<endl;
}

四、ni

problem ni

 

贝茜在卡米洛特遇到一种情况:她需要通过一个被Ni的骑士守卫的树林。为了安全地通过,骑士需要贝茜给他们带一个灌木。时间是极重要的,贝茜必须尽可能快的找到并且给他们带去一个灌木。

 

贝茜有树林的地图,被分割成方形的格子,平行于XY轴。地图大小是W*H1=W=10001=H=1000)。

 

地图展示贝茜从哪里开始,Ni的骑士的位置,所有灌木的位置。也展示哪些地区可以通过(一些格子因为沼泽、悬崖、杀手不能通过)。贝茜不能不带一个灌木就去通过Ni的骑士。

 

为了确定贝茜正确沿着地图走,贝茜只可以沿着四个方向走:北,东,南,或者西(不能对角)。她从一个格子走到相邻的格子需要花费1天时间。

 

保证贝茜可以拿到一个灌木然后交给Ni的骑士。帮她确定最快的路线去走。

 

题目名字:ni

 

输入样例:

*第一行:两个分开的整数:WH

*第二....?:地图的描述,共有W*H整数,表示上述的地图,但换行符不确定。

地图上的整数描述:

0:贝茜可以通过;

1:贝茜不可以通过;

2:贝茜开始的位置;

3:Ni的骑士位置;

4:灌木的位置;

 

输出样例:

8 4

4 1 0 0 0 0 1 0

0 0 0 1 0 1 0 0

0 2 1 1 3 0 4 0

0 0 0 4 1 1 1 0

 

输入解释:

=8,高度=4。贝茜从第3行出发,只有一些方格远离骑士.

 

输出格式:

*第一行:D,贝茜到达一个灌木然后带给Ni的骑士所需的最小天数。

 

输出样例:

11

 

输出解释:

N, W, N, S, E, E, N, E, E, S, S

 

【题目分析】

这题一看题就知道是典型的宽度搜索题目,只是多了个条件,即必须要先拿到灌木。但其实也很简单。我们只需要用两个BFS,第一次计算贝茜到每个灌木的最短距离,第二次计算骑士到每个点的距离,然后加起来,计算哪个灌木的总距离最小。

 

【例程】

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int n,w,h;
char num[1002][1002];
int a[]={-1,0,1,0},b[5]={0,1,0,-1};
int xx=0,yy=0,ll=0,ans=1000*1000+1,ge=0;
int jlx,jly,jx,jy;
bool bo[1002][1002],bo2[1002][1002];
int way[1002][1002];
int guan=0,guan2;

struct lj
{
int x,y,l;
};
lj d[1000*1000*4],d2[1000*1000*4];

int main()
{
freopen("ni.in","r",stdin);
freopen("ni.out","w",stdout);

cin>>w>>h;
memset(num,'1',sizeof(num));
memset(bo,false,sizeof(bo));
memset(bo2,false,sizeof(bo2));
memset(way,0,sizeof(way));

for(int i=1;i<=h;++i)
for(int j=1;j<=w;++j)
{
cin>>num[i][j];
if(num[i][j]=='0')
{
bo[i][j]=true;bo2[i][j]=true;
}
if(num[i][j]=='2')
{
jx=i;jy=j;
}
else
if(num[i][j]=='3')
{
jlx=i;jly=j;
}
else
if(num[i][j]=='4')
{
++guan;bo[i][j]=true;bo2[i][j]=true;
}
}

guan2=guan;

int H=0,T=0;
d[0].x=jx;
d[0].y=jy;
d[0].l=0;

while(H<=T)
{
xx=d[H].x;
yy=d[H].y;
ll=d[H].l;

if(num[xx][yy]=='4')
{
--guan;
way[xx][yy]=ll;
//cout<<"guan"<<guan2-guan<<":"<<ll<<endl;
if(guan==0)
break;
}

for(int i=0;i<4;++i)
{
if(bo[xx+a[i]][yy+b[i]])
{
++T;
d[T].x=xx+a[i];d[T].y=yy+b[i];
d[T].l=ll+1;
bo[d[T].x][d[T].y]=false;
}
}
++H;
}

H=0,T=0;
d[0].x=jlx;
d[0].y=jly;
d[0].l=0;
guan=guan2;
bo2[jx][jy]=true;

while(H<=T)
{
xx=d[H].x;
yy=d[H].y;
ll=d[H].l;

if(num[xx][yy]=='4')
{
way[xx][yy]+=ll;
///cout<<way[xx][yy]<<"!"<<endl;
if(way[xx][yy]<ans&&!bo[xx][yy])
ans=way[xx][yy];
guan2--;
//cout<<"guan2_"<<guan-guan2<<":"<<ll<<endl;
if(guan2==0)
break;
}

for(int i=0;i<4;++i)
{
if(bo2[xx+a[i]][yy+b[i]])
{
++T;
d[T].x=xx+a[i];d[T].y=yy+b[i];
d[T].l=ll+1;
bo2[d[T].x][d[T].y]=false;
}
}
++H;
}

cout<<ans<<endl;
return 0;
}



 

0 0
原创粉丝点击