hihocoder 1509 异或排序(模拟)

来源:互联网 发布:新网域名如何过户 编辑:程序博客网 时间:2024/05/16 23:33

题目链接:http://hihocoder.com/problemset/problem/1509

解题方案:首先,两个数谁大谁小一定是看这两个数的高位里面第一个不相同的数字,不管是10进制还是2进制都是这样判断。然后可以将所有的a[i]看成是60位的二进制数,a[i]和a[i+1]二进制串相同的地方和s异或后一定还是一样的,不同的地方和s异或后一定还是不一样的,因为(0,1)^0=(0,1),(0,1)^1=(1,0),(0,0)^0=(0,0),(1,1)^1=(0,0)。所以s的二进制串若想满足题意,对a[i]和a[i+1]高位里面第一个不相同的位置j,s[j]是固定的。故只需要将s所有固定的位置的值求出来,期间判断一下是否出现矛盾,然后就可以算出符合题意的s的个数了。

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define FOR(i,k,n) for(int i=k;i<n;i++)#define FORR(i,k,n) for(int i=k;i<=n;i++)#define scan(a) scanf("%d",&a)#define scann(a,b) scanf("%d%d",&a,&b)#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)#define mst(a,n)  memset(a,n,sizeof(a))#define ll long long#define N 65#define mod 1000000007#define INF 0x3f3f3f3fconst double eps=1e-8;const double pi=acos(-1.0);int a[N][N];int s[N];int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n;    while(cin>>n)    {        mst(a,0);        mst(s,-1);        FOR(i,0,n)        {            ll tmp;            cin>>tmp;            int cnt=0;            while(tmp)            {                a[i][cnt++]=tmp&1;                tmp>>=1;            }        }        int flag=1;        FOR(i,0,n-1)        {            if(!flag) break;            for(int j=59;j>=0;j--)            {                if(a[i][j]!=a[i+1][j])                {                    if(a[i][j]==0&&a[i+1][j]==1)                    {                        if(s[j]==1)                        {                            flag=0;                            break;                        }                        s[j]=0;                    }                    else                    {                        if(s[j]==0)                        {                            flag=0;                            break;                        }                        s[j]=1;                    }                    break;                }            }        }        if(!flag) printf("0\n");        else        {            int cnt=0;            FOR(i,0,60) if(s[i]==-1) cnt++;            //printf("%d\n",cnt);            cout<< ((ll)(1)<<cnt) <<endl;        }    }    return 0;}


0 0
原创粉丝点击