hdu 4876(剪枝+暴力)

题意:给定n,k,l,接下来给出n个数,让你从n个数中选取k个数围成一圈,然后从这k个数中随意选出连续的m(m>=1&&m<=k)个数进行异或后得到[l,r]区间的所有值,让你求最大的r。

分析:关键问题是需要剪枝!

2014 <wbr>Multi-University <wbr>Training <wbr>Contest <wbr>2--by <wbr>镇海中学 <wbr>解题报告

代码实现:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<set>
#include<vector>

using namespace std;

int n,k,L,R,a[25],b[10],id;
int visited[130];
string str[10] = {"1", "12", "123", "1234", "12345", "123456"};

int check()
{
    int i,j,temp[1005],tot=0,t;
    temp[tot++]=0;

    for(i=0;i<k;i++)//枚举所有的组合异或值
    {
        t=tot;
        for(j=0;j<tot;j++)
            temp[t++]=b[i]^temp[j];
        tot=t;
    }

    for(i=0;i<tot;i++)
        visited[temp[i]]=id;

    for(i=L;i<=R;i++)
        if(visited[i]!=id)
            return 0;
    return 1;
}

void dfs(int x, int num)
{
    int i,j;
    if(num==k)
    {
        id++;
        if(check()==0)
           return ;
        string per = str[k-1];
        
        do
        {
            if(per[0]!='1')//这里去除了很多重复的,没加这句话500ms,加了之后100ms
                break;
            id++;
            int temp[12];
            for(i=0;i<k;i++)
            {
                temp[i]=b[per[i]-'0'-1];
                temp[i+k]=temp[i];
            }

            for(i=0;i<k;i++)
            {
                int flag=0;
                for(j=i;j<i+k;j++)
                {
                    flag=flag^temp[j];
                    visited[flag]=id;
                }
            }

            if(visited[L]!=id)
                continue;
            i=L+1;
            while(visited[i]==id)
             i++;
            R=R>(i-1)?R:(i-1);
            
        }
        while(next_permutation(per.begin(),per.end()));

        return ;
    }

    for(i=x;i<n;i++)
    {
        b[num]=a[i];
        dfs(i+1,num+1);
    }
}

int main()
{
    int i;
    while(scanf("%d%d%d",&n,&k,&L)!=EOF)
    {
        id=0;R=0;
        memset(visited,-1,sizeof(visited));
        for(i=0; i<n; i++)
            scanf("%d",&a[i]);
        dfs(0,0);
        printf("%d
",R);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jiangjing/p/3868662.html