zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    字符串的字典排序
    最长上升子序列LIS(Longest Increasing Subsequence)
    小猴子下落
    二叉树的遍历
    7,Uipath实践-从零开始写demo-UiPath Foreach循环
    6,UiPath实践-从零开始写demo-if判断
    5,Uipath实践-从零开始写demo-调试Get Mail
    3,UiPath实践-从零开始写demo-读取Email
    4,Uipath实践-从零开始写demo-Uipath调试
    2,UiPath探索-Hello World
  • 原文地址:https://www.cnblogs.com/jiangjing/p/3868662.html
Copyright © 2011-2022 走看看