scu集训队第二次周赛记录

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

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;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值