2017.11.16考试总结题解
一、恐怖服装
题目简述:农夫有一件长为s的恐怖服装,同时他又有n(2 <= N <= 20,000)头奶牛,第i头奶牛的长度为Li。且恐怖服装最多只能容纳两头奶牛。他想要他的其中两头奶牛穿上恐怖服装,问共有几种满足?
分析:根据题意可知,如果是纯粹的双重循环判断,肯定会超时。那么我们就得进行适当的剪纸来减少循环,这时就用到了排序(从小到大),如果外循环与内循环相加的和大于S,那么就内退出循环,因为如果当前较小的奶牛长度加上外循环的奶牛长度都长于S,那么接下来就肯定大于了,就不用浪费时间了(当时居然崩了,可看出我的多么不细心,不过我会努力改正的!也许吧)。
那么代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
long int a[20001],i,j,n,sum=0,s,m,t;
cin>>n>>s;
for (i=1;i<=n;i++) scanf("%d",&a[i]);//scanf也能尽量的减少时间
sort(a+1,a+n+1);//排序
for (i=1;i<=n-1;i++){
for (j=i+1;j<=n;j++)
if (a[i]+a[j]<=s) sum++;//满足条件,次数累加
else break;//剪枝,退出循环。
}
cout<<sum;
return 0;
}
二、密码锁
题目简述:农夫的奶牛一直从他的农场逃离并且导致了巨额损失。
为了阻止它们逃离,他找来了一只神奇的锁来阻止他的奶牛打开栅栏门。
这个锁有三个密码子,每个都是从1-n的整数(1<=n<=100),1和n是相邻的,因为这些密码子是一个圈。有两组密码能够打开这个锁,一个是农夫的,另一个是锁匠的。然而,这个锁有一个小的容错的几率,它会打开只要表盘上的数字位置与任意一个密码上的相应数字位置相差不超过2。比如,如果农夫的密码是(1,2,3),锁匠的密码是(4,5,6)。如果你的输入是(1,n,5)(因为这和农夫的密码很相近)或者是(2,4,8)(因为这和锁匠的密码很接近),这个锁都会打开。注意,(1,5,6)无法打开这个锁,因为它和任何一个密码都不接近。
分析:这题是有一个坑的,因为锁是呈环状排列,所以n和1也是相邻的。首先,我们知道可能性一共就250(想想,为什么),那么我们就得循环判断它们每个位置对应的差是否相差二,如果是,就不管;不然种数减一。
那么代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
long int n,x,x1,x2,y,y1,y2,sum=250,i1,i2,i3,i4,i5,i6,a1,a2,a3,a4,a5,a6;
cin>>n;
scanf("%d %d %d",&x,&x1,&x2);
scanf("%d %d %d",&y,&y1,&y2);
for (i1=x-2;i1<=x+2;i1++)
for (i2=x1-2;i2<=x1+2;i2++)
for (i3=x2-2;i3<=x2+2;i3++)
for (i4=y-2;i4<=y+2;i4++)
for (i5=y1-2;i5<=y1+2;i5++)
for (i6=y2-2;i6<=y2+2;i6++){/六个循环/循环可能的密码
if (i1<=0) a1=n+i1;else a1=i1;
if (i2<=0) a2=n+i2;else a2=i2;
if (i3<=0) a3=n+i3;else a3=i3;
if (i4<=0) a4=n+i4;else a4=i4;
if (i5<=0) a5=n+i5;else a5=i5;
if (i6<=0) a6=n+i6;else a6=i6;//留个判断针对环的情况
if ((a1==a4)&&(a2==a5)&&(a3==a6))//重复
sum--;//次数减一
}
cout<<sum;
return 0;
}
三、采蘑菇的拖拉机
题目简述:农夫的农场被分为了一个平面坐标系,最左下角的坐标为(1,1),最右上角的坐标为(10^5,10^5).
农夫有一个探测蘑菇的雷达,当开启蘑菇雷达后,这个雷达每一秒会发现农场上的一个蘑菇,并且会告知这个蘑菇的坐标。
农夫的奶牛只会沿着一个方向开拖拉机,并且不会拐弯,这里的方向指的是和坐标轴平行的四个方向和与坐标轴夹角45度的对角线(当然是两条对角线)。并且每天朱昶成只允许奶牛开一次拖拉机,也就是说,每次采蘑菇,拖拉机只能沿着一个方向去采集所经过的点的蘑菇。
农夫允许他的奶牛从农场里的任意一个点,任意一个方向出发,并且他的拖拉机的速度奇快,从启动到完成任务话费的时间忽略不计。现在朱昶成想直到,如果要一次性的采集K个蘑菇,最早在什么时间完成任务。
分析:这道题其实不难看出是一道典型的八皇后变形版。把把上下左右以及左右下角的对角线的行列数规律弄清楚后,就不难做出这题。规律为:上下同列就是列数相等;左右同行就是行数相等;左对角线相等就是行列和相等;右对角线相等就是差相等。那么了解这些规律后这道题就变成了很简单的一题相加判断题。
具体代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[100001]={},b[100001]={},c[100001]={},d[100001]={},n,x,y,k;//a为左右相等(记录行的蘑菇个数),b就为上下相等(记录列的蘑菇个数),c数组就位右对角线相等(记录右对角线的蘑菇个数),d数组为左对角线相等(记录左对角线的蘑菇个数)
bool f=1,f1=1;//f为记录是否采到了蘑菇,f1的作用下面会将
cin>>n>>k;
for (int i=1;i<=n;i++){
cin>>x>>y;
a[x]++;
b[y]++;
c[abs(x-y)]++;
d[x+y]++;//记录相应位置的蘑菇个数
if ((a[x]>=k||b[y]>=k||c[abs(x-y)]>=k||(d[x+y]>=k))&&f1//f1为判断是否已经采到了k个蘑菇,需要记录,不然输入会有问题){//条件判断
cout<<i<<endl;//输出
f1=0;
f=0;//置为false
}
}
if (f)cout<<-1<<endl;//如果没猜到,就-1
f=1;f1=1;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));//清空数组
cin>>n>>k;
for (int i=1;i<=n;i++){
cin>>x>>y;
a[x]++;
b[y]++;
c[abs(x-y)]++;
d[x+y]++;
if ((a[x]>=k||b[y]>=k||c[abs(x-y)]>=k||(d[x+y]>=k))&&f1){
cout<<i;
f1=0;
f=0;
}
}
if(f)cout<<-1;、//同理
}
四、
想把一个普通的英语单词转换成牛语很简单.如果一个单词的以一个元音字母('a','e','i','o','u)开头,那么只需在 这个单词的结尾加上"cow".例如,"udder"需要变成"uddercow"; 如果一个单词的第一个字母不是元音字母,那么只需把这个单词的第一个字母放到单词结尾,然后再在结尾加上"ow".例如 "farmer"需要变成"armerfow". 所以"the cows escape at dawn"就会变成"hetow owscow escapecow atcow awndow."你需要将N (1 ≤ N ≤ 100)个英语单词翻译成牛语,单词长度在3到40之间.。
分析:这道题其实也没什么可以讲,纯模拟就行,模拟的题目最重要的其实就是多看代码以及多打代码。
那么代码如下:
#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int lena,lenb;
void change(){
s2.erase(0,s2.size());//将s2清空,这里的erase是字符串中的删除函数
if (s1[0]=='a'||s1[0]=='e'||s1[0]=='i'||s1[0]=='o'||s1[0]=='u'){//判断首位是否为”a,e,i,o,u”
s2=s1+"cow";return;//如果是,那么就在末尾加上cow
}//接下来就不用条件判断了,因为如果满足条件就会跳出循环
for (int i=1;i<=s1.size()-1;i++) s2=s2+s1[i];//将前面的字母加上
s2=s2+s1[0]+"ow";//加上最后的字母在补一个ow
}
int main(){
int n,m,k,x;
cin>>n;
for (int i=1;i<=n;i++){
cin>>s1;
change();//处理
cout<<s2<<endl;//输出
}
return 0;
}//这道字符串其实算水题了吧
结束心得:在考试时不能慌张,仔细地分析题目、解剖题目、了解题目、在与题目融为一体,这样你就会对题目有无限的思路,会发现某些题目其实也没那么难,只要你静得下心,就能够做到!!(心得十分重要! 心得十分重要! 心得十分重要!重要的事说三遍)