UVALive-7357-Pyro Tubes

题目链接:点击打开链接

题目大意:
给定一个单调递增的数字序列,求每一个数字与其后面的数字中用二进制串表示时最多只有两个位置不同的数的数目。
解题思路:
这个题显然可以想到两种思路:
一:对于每一个数依次判断其后面的数是否满足条件,而总个数有2.5X1e5,显然TLE;
二:对于每一个数求:满足用二进制串表示时最多只有两个位置不同的数,然后判断这个数是否在给出的序列中,求和。因为用二进制串表示后最多只有18个位置,两个位置不同的 数量就是18*17/2,一个位置不同就是18个,这样的复杂度就不高了。求每一个数的时候,假如要改变某一个位置上的值,那么就将这一位与1进行异或。
代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e6;
bool vis[maxn];
int a[maxn],ans;
inline bool scan_d(int &num){
    char in;bool IsN=false;
    in=getchar();
    if(in==EOF) return false;
    while(in!='-'&&(in<'0'||in>'9')) in=getchar();
    if(in=='-'){ IsN=true;num=0;}
    else num=in-'0';
    while(in=getchar(),in>='0'&&in<='9'){
        num*=10,num+=in-'0';
    }
    if(IsN) num=-num;
    return true;
}
void solve(int x){
    ans=0;
    for(int i=0;i<18;i++){
        for(int j=0;j<=i;j++){
            int res=(1<<i);
            res^=x;
            if(i!=j)res^=(1<<j);
            if(res>x&&vis[res]){
                ans++;
            }
        }
    }
    printf("%d:%d\n",x,ans);
}
int main(){
//    freopen("in.txt","r",stdin);
    int cnt=0,num;
    while(scan_d(num)){
        if(num!=-1){
            a[cnt++]=num;
            vis[num]=1;
            continue;
        }
        for(int i=0;i<cnt;i++)solve(a[i]);
        cnt=0;memset(vis,0,sizeof vis);
    }

    return 0;
}

这个题应该写出来的呀 抓狂,第二种思路好像在脑子里闪过一次的样子,不知道怎么就没想了...。然后还去把所有的二进制串建成了一颗树,后面一想,貌似并没有什么卵用,遍历的时候复杂度并没有降低,就当作练习了一下字典树吧 哭
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值