背景:五题出四题,最后一道题对数学思维有考研,在压力之下没能够深入思考,以后要注意了。然后这些题其实难度都不大,因为自己没有严格遵循读完题就自己写五个测试数据的好习惯,以后些题得注意了。
A题:判断合数,无它。
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define M 1009
#define INF 0x3fffffff
#define LL long long int
using namespace std;
bool isnp(int x){
bool ok=false;
if(x > 2)
for(int i=2;i*i <= x;i++){
if(x%i == 0) ok=true;
}
return ok;
}
int main(void){
int n;
scanf("%d",&n);
for(int i=3;i <= n;i++){
if(isnp(i) && isnp(n-i)){ printf("%d %d",i,n-i);break;}
}
return 0;
}
B题:排序加贪心:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#define M 2009
#define INF 0x3fffffff
using namespace std;
int str[M];
int main(void){
int n,k,step=0;
scanf("%d%d",&n,&k);
for(int i=0;i < n;i++) scanf("%d",&str[i]);
sort(str,str+n);
for(int i=n-1;;i-=k){
if(i <= k-1){step+=(str[i]-1)*2;break;}
step+=(str[i]-1)*2;
}
printf("%d",step);
return 0;
}
c题:开始竟然wa了三次,没有读懂题意,没有深刻理解并想好算法再开做。开始都有点想放弃了,看到luoxincheng做出来了,我也一定能做出来了,就ac了,看来李大神说的暗示自己绝对做的出来就是正确的!。题目本身主要是只要满足两个相邻的后一个大于前一个就好了,然后简单的贪心。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#define M 200009
#define INF 0x3fffffff
#define LL long long int
using namespace std;
char str[100009][2][60];
int list[100009];
int main(void){
int n;
scanf("%d",&n);
memset(str,'\0',sizeof(str));
for(int i=1;i <= n;i++) {scanf("%s%s",str[i][0],str[i][1]);if(strcmp(str[i][0],str[i][1]) <= 0) swap(str[i][0],str[i][1]);}
for(int i=1;i <= n;i++) scanf("%d",&list[i]);
bool ok=true;
for(int i=1;i <= n-1;i++){
int j=i+1;
bool key=false;
if(str[list[i]][0][0] >= 'a' && str[list[j]][1][0]>='a' && strcmp(str[list[i]][0],str[list[j]][1]) < 0){
str[list[i]][1][0]='a'-1;
str[list[j]][0][0]='a'-1;
key=true;
}else if(str[list[i]][1][0] >= 'a' && str[list[j]][1][0]>='a'&& strcmp(str[list[i]][1],str[list[j]][1]) < 0){
str[list[i]][0][0]='a'-1;
str[list[j]][0][0]='a'-1;
key=true;
}else if(str[list[i]][0][0] >= 'a' && str[list[j]][0][0]>='a'&& strcmp(str[list[i]][0],str[list[j]][0]) < 0){
str[list[i]][1][0]='a'-1;
str[list[j]][1][0]='a'-1;
key=true;
}else if(str[list[i]][1][0] >= 'a' && str[list[j]][0][0]>='a'&& strcmp(str[list[i]][1],str[list[j]][0]) < 0){
str[list[i]][0][0]='a'-1;
str[list[j]][1][0]='a'-1;
key=true;
}
if(!key){ok=false;break;}
}
if(ok) printf("YES");
else printf("NO");
return 0;
}
D题:排序之后二分查找,自己写的二分查找。这里可以学习STL的关于查找的三个函数:lower_bound(),upper_bound(),binary_serch().
如果该元素在序列(必须为有序序列,即二分查找的前提)存在着,lower_bound(str,str+n,x) 值x所在地的迭代器,upper_bound()返回值x所在地的下一个迭代器(这里迭代器就是具体的数组元素地址名),而binary_serch()返回true,即存在该元素。
如果该元素在序列中不存在,lower_bound()和upper_bound()都返回假象该元素在序列中存在的应该位置的迭代器,binary_serch()返回false。
我的代码:
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define M 9000
#define INF 0x3fffffff
#define LL long long int
int str[100009];
int main(void){
int n,m;
scanf("%d",&n);str[0]=0;
for(int i=1;i <= n;i++){
int c;
scanf("%d",&c);
str[i]=str[i-1]+c;
}
scanf("%d",&m);
while(m--){
int c;
scanf("%d",&c);
if(str[n-1] < c){printf("%d\n",n);}
else if(str[1] >= c ){printf("1\n");}
else {
int up=n,down=1,mid;
while(1){
mid=(up+down)/2;
if(str[mid] >= c && str[mid-1] < c){printf("%d\n",mid);break;}
if(str[mid] >= c) up=mid;
else down=mid+1;
}
}
}
return 0;
}
用stl的lower_bound()之后代码量减少了不止一点!!用lowerbound之后的代码:
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define M 9000
#define INF 0x3fffffff
#define LL long long int
using namespace std;
int str[100009];
int main(void){
int n,m;
scanf("%d",&n);str[0]=0;
for(int i=1;i <= n;i++){
int c;
scanf("%d",&c);
str[i]=str[i-1]+c;
}
scanf("%d",&m);
while(m--){
int c;
scanf("%d",&c);
printf("%d\n",lower_bound(str+1,str+n+1,c)-str);
}
return 0;
}
E题:赛场上想了30多分钟却仍然没有想好思路的题,下来想了好久才明白,是一道数学规律类的题。赛场上碰到这种思维题,应该相信自己加快思维速度与创造力,想出解法。
我的思路:首先求出n张牌所能累积的最大高度,然后每三层可以降一层,因为每一层的牌数取余3为2,这样3层多出来的2,就为6,6为三的整数倍就可以降层了。然而其中求n张牌所能达到的最高楼层要用到推导的公式。
我的代码:
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define M 209
#define INF 0x3fffffff
#define LL long long int
using namespace std;
LL cal(LL i){
return ((i*i*3)+i)/2;
}
int main(void){
LL n;
int pile=0;
scanf("%I64d",&n);
for(int i=0;i <= n;i++){
if(cal(i) <= n && n < cal(i+1)){
for(;i >= 1;i--) if( (n-cal(i))%3 == 0){pile=i;break;}
break;
}
}
int ans=1;
if(!pile) printf("0");
else{
ans+=(pile-1)/3;
printf("%d",ans);
}
return 0;
}