BestCoder Round #61 (div.2)

比赛的时候过了两道,第三道超时20分钟过得

A题简单,我用了17分钟才写出来,看了界面熊大大的status,四分钟,直接把我吓傻,看了他的代码才知道,与大大之间的差距有多大:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>

#define LL long long

#define pir pir <int,int>

#define m_p make_pair

#define mod 1000000007

using namespace std;

int n,a[1005],f[5005];

int main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    //int T;scanf("%d",&T);
    while(scanf("%d",&n)==1){
        memset(f,0,sizeof(f));
        for(int i=0;i<n;++i){
            scanf("%d",a+i);
            f[a[i]]++;
        }
        bool flag=false;
        for(int i=0;i<n;++i){
            for(int j=i+1;j<n;++j){
                f[a[i]]--;
                f[a[j]]--;
                if(f[a[i]+a[j]]>=1){
                    flag=true;break;
                }
                f[a[i]]++;
                f[a[j]]++;
            }
            if(flag)break;
        }
        if(flag)puts("YES");
        else puts("NO");
    }
    return 0;
}
思路和代码风格都很巧妙,恩,感觉我的代码就是屌丝代码
以下是我的版本(跟大大的代码放在一起简直是献丑了TT):

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define MAXN 110
#define MAXM 1100
using namespace std;

int n;

struct node{
    int value,index;
    bool operator<(node other)const{
        return value<other.value;
    }
}s[MAXN];

int bsearch(int front,int rear,int value){
    int mid;
    while(front<rear){
        mid=(front+rear)>>1;
        if(s[mid].value>=value)
            rear=mid;
        else
            front=mid+1;
    }
    return front;
}

int main(){
    while(cin>>n){
        for(int i=1;i<=n;i++){
            cin>>s[i].value;
            s[i].index=i;
        }
        sort(s+1,s+n+1);
        for(int i=1;i<n;i++){
            for(int j=i+1;j<=n;j++){
                int sub=s[j].value-s[i].value;
                int pos=bsearch(1,n,sub);
                while(pos<=n&&s[pos].value==sub){
                    if(s[pos].index!=s[i].index&&s[pos].index!=s[j].index){
                        cout<<"YES"<<endl;
                        goto next;
                    }
                    pos++;
                }
            }
        }
        cout<<"NO"<<endl;
next:
        {}
    }
    return 0;
}
B题我一次AC,一方面是运气比较好,一开始思路就是对的。另一方面不得不说,前几天的组合数学不是白看的。虽然只看了第一章的排列组合,但做这些题的时候明显感觉自己思路清晰了很多。还记得汉舟学长说过的话“要与数学这位老大哥做好朋友”。现在才有点领会到学长的意境了。

具体分类的方法见代码里的注释:

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

int main(){
    int n,s,t;
    while(cin>>n>>s>>t){
        if(s==t){
            if(n==1)
                cout<<0;
            else
                cout<<-1;
        }
        else{
            if(s>1&&s<n&&t>1&&t<n&&abs(s-t)>1){//中间不挨着
                cout<<2;
            }
            else if(s>1&&s<n&&t>1&&t<n&&abs(s-t)==1){//中间挨着
                cout<<1;
            }
            else if(s>1&s<n&&(t==1||t==n)&&abs(s-t)>1){//我中间他边上不挨着
                cout<<2;
            }
            else if(s>1&s<n&&(t==1||t==n)&&abs(s-t)==1){//我中间他边上挨着
                cout<<1;
            }
            else if(t>1&t<n&&(s==1||s==n)){//他中间我边上
                cout<<1;
            }
            else if((s==1||s==n)&&(t==1||t==n)){//都在边上
                cout<<0;
            }
        }
        cout<<endl;
    }
    return 0;
}

C题是完全二叉树,complete binary tree 应该是程序员最喜欢的数据结构之一了吧。看见二叉树,而且是完全的,就应该兴奋起来。可惜我手速慢了。而且,代码写的不够清晰,所以导致最后debug的时候很困难,还有对stl不熟,一边写代码一边还要查资料简直不能再这样了。凡是遇到自己都觉得不清晰的代码,就应该重写吧

#include<cstdio>
#include<iostream>
#include<set>
#include<map>
#include<algorithm>
#define LL long long
using namespace std;

set<LL>table;
map<LL,LL>mapp;
set<LL>ans;
LL maxvis;

void init(){
	for(LL i=0;i<63;i++){
		table.insert(1LL<<i);
		mapp[1LL<i]=i;
	}
}

void add(LL n){
	//cout<<"add"<<n<<endl;
	while(n>=0){
		ans.insert(n);
		n=(n+2)/2-2;
	}
}

LL get(LL n){
	LL ret=0;
	while(n>1){
		ret++;
		n/=2;
	}
	return ret;
}

void bfind(LL n){
	if(n<0)
		return ;
	if(n==0LL){
		ans.insert(0LL);
		return ;
	}
	if(table.count(n+2)>0){
		LL layer=mapp[n+2];
		if(layer>=maxvis){
			add(n);
			maxvis=layer;
		}
	}
	else{
		ans.insert(n);
		LL cengshu=get(n+1);
		LL shangmian=(1LL<<cengshu)-1;//这个地方写成了小于号,调了半天没发现
		LL left=(((1LL<<(cengshu-1))<=(n+1-shangmian))?(1LL<<(cengshu-1)):(n+1-shangmian));
		LL leftshangmian=shangmian/2+left;
		LL right=n-leftshangmian;
		bfind(leftshangmian-1);
		bfind(right-1);
	}
}

int main(){
	LL n;
	init();
	//for(set<LL>::iterator i=table.begin();i!=table.end();i++)
	//	cout<<*i<<' ';
	while(cin>>n){
		maxvis=-1;
		bfind(n-1);
		cout<<ans.size()<<endl;
		//	for(set<LL>::iterator i=ans.begin();i!=ans.end();i++)
	//		cout<<*i<<' ';
		ans.clear();
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值