scu集训队第二次周赛记录

来源:互联网 发布:交流网络 编辑:程序博客网 时间:2024/05/19 23:09

背景:五题出四题,最后一道题对数学思维有考研,在压力之下没能够深入思考,以后要注意了。然后这些题其实难度都不大,因为自己没有严格遵循读完题就自己写五个测试数据的好习惯,以后些题得注意了。

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 intusing 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 0x3fffffffusing 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 intusing 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 intint 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 intusing 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 intusing 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;}





0 0