CF#247(Div. 2)部分题解

4 篇文章 0 订阅

自从省赛结束后,我就很少刷题了,虽然泡ACM不久,仅有一年多点,但是这已经是我的生活习惯了,有些东西不是说放弃就能放弃的,我想有可能我也想参加区预赛。

就算不能参加,我也不能放弃ACM,我决定每天早上早起来刷至少一题再弄其他,记得早起的时候要追溯到学习java的时光了……好啦,不废话了~

A题,签到题,看着样例都能过了。

/*************************************************************************
	> OS     : Linux 3.2.0-60-generic #91-Ubuntu
	> Author : yaolong
	> Mail   : dengyaolong@yeah.net 
	> Created Time: 2014年05月21日 星期三 23:25:30
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char str[100005];
int main(){
    int a[5],sum=0;
    int len=strlen(str);
    scanf("%d%d%d%d",a+1,a+2,a+3,a+4);
    scanf("%s",str);
    while(len--){
        sum+=a[str[len]-'0'];
    }
    printf("%d\n",sum);
    return 0;
}
B题,O(n!)的算法,算是比较恶心的暴力题,不过还是很简单。遍历所有的可能,再根据给出的公式,毫无压力。

/*************************************************************************
	> OS     : Linux 3.2.0-60-generic #91-Ubuntu
	> Author : yaolong
	> Mail   : dengyaolong@yeah.net 
	> Created Time: 2014年05月21日 星期三 23:25:46
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[10][10];
int count(int i1,int i2,int i3,int i4,int i5){

    int r1= a[i1][i2]+a[i2][i1]+a[i3][i4]+a[i4][i3];
    int r2= a[i2][i3]+a[i3][i2]+a[i4][i5]+a[i5][i4];
    int r3= a[i3][i4]+a[i4][i3];
    int r4= a[i4][i5]+a[i5][i4];
    return r1+r2+r3+r4;
}
int main(){
    int i,j;
    for(i=1;i<=5;i++){
        for(j=1;j<=5;j++){
            scanf("%d",&a[i][j]);
        }
    }
    int mmax=-1;
    int i1,i2,i3,i4,i5;
    for(i1=1;i1<=5;i1++){
      for(i2=1;i2<=5;i2++){
          if(i1==i2){
              continue;
          }
        for(i3=1;i3<=5;i3++){
            if(i1==i3||i2==i3){
                continue;
            }
          for(i4=1;i4<=5;i4++){
              if(i1==i4||i2==i4||i3==i4){
                  continue;
              }
              for(i5=1;i5<=5;i5++){
                  if(i1==i5||i2==i5||i3==i5||i4==i5)
                  {
                      continue;   
                  }    
                  int tmp=count(i1,i2,i3,i4,i5);
                  if(tmp>mmax) mmax=tmp;
              }
        }
      }
    }
    }
    printf("%d",mmax);    
    return 0;
}

D题,当时我没有做下去,因为我困了~我玩cf不刷rating求的是气氛,所以累了我就休息了。

这题目相对没那么简单,也蛮有意思的题目。

题目就是:给定m,k,输出一个n(多种解),使得n+1,n+2,……,2*n中恰好有m个数的二进制恰好有k个1。比如m=3,k=2时候,n=6为其中一个解。

从(110,1100],有且只有1001,1010,1100(9,10,12)这三个数的二进制的1的个数为2。

思路:首先,我们要知道这是一个随n递增的函数,非常容易证明:n+1,n+2,..,(2*n)中二进制恰好有k个个数为p,当n++后,即n+2,....2*n,2*n+1,2*(n+1),注意到2*(n+1)与n+1的二进制1的个数是一样的,那么引起改变的只有2*n+1,即最多不减。

那么我们就可以用二分来搞了,二分的思路就是,计算rt=10^8,lt=1,那么我们计算(1~2*mid)-(1~mid)满足的个数如果等于m就break掉,比m小lt=mid+1,否则rt=mid-1。

接下来的问题就是如何搞1~X中恰好为k的个数了,其实也是很简单的。我们用一个计数器,表示已经统计了多少位,从最高位往最低搞起,当前“1”位是第i个(起始从0开始啊!),那么我们可以有C(i,k-cnt)个搞法(从第0位到第i-1各中选出k-cnt个,大于等于i的位全部已经定下来了)之后cnt++。(记得要判断k>cnt,不然就像我一开始WA无限)。

另外,这道题的组合数果断用杨辉三角来搞啊!

/*************************************************************************
	> OS     : Linux 3.2.0-60-generic #91-Ubuntu
	> Author : yaolong
	> Mail   : dengyaolong@yeah.net 
	> Created Time: 2014年05月22日 星期四 07:19:55
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef  long long LL;
LL C[70][70],m;
int k;
void init(){

    int i,j;
    for( i=0;i<=64;i++){
        C[i][0]=C[i][i]=1;
    }
    for(i=2;i<=64;i++){
        for(j=1;2*j<=i;j++){
            C[i][j]=C[i][i-j]=C[i-1][j-1]+C[i-1][j];
        }
    }

}
LL F(LL X){

    LL ans=0;
    int i,cnt=0;
    int max_bit=0;
    LL tmp=X;
    while(tmp>1){
        max_bit++;
        tmp>>=1;
    }

    for ( i=max_bit;i>=0;i--){
        if((X>>i)&1){
            if(k>cnt)
            ans+=C[i][k-cnt];
            cnt++;
        }
    }
    if(cnt==k)ans++;
    return ans;
}
LL cal(LL num){
    return F(num*2)-F(num);
}
int main(){

    init();
    cin>>m>>k;
    LL lt=1,rt=1000000000000000000LL;
    LL ans=0;
    while(lt<=rt){
        LL mid=(lt+rt)>>1;
        LL tmp=cal(mid);
        if(tmp==m){
            ans=mid;
            break;
        }
        if(tmp<m){
            lt=mid+1;
        }else{
            rt=mid-1;
        }
    }
    cout<<ans;
    return 0;
}


抱歉,根据提供的引用内容,我无法理解你具体想要问什么问题。请提供更清晰明确的问题,我将竭诚为你解答。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Codeforces Round 860 (Div. 2)题解](https://blog.csdn.net/qq_60653991/article/details/129802687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【Codeforces】 Codeforces Round 865 (Div. 2) (补赛)](https://blog.csdn.net/t_mod/article/details/130104033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Codeforces Round 872 (Div. 2)(前三道](https://blog.csdn.net/qq_68286180/article/details/130570952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值