hdu5536 Chip Factory (暴力+优化)

暴力+优化

话说网上有字典树的正规解法,不过hdu重现赛时并不会,于是直接暴力了。

优化方式直接在代码注释中标注了,这里不详解了。

#include 
#include 
using namespace std;

const int MAXN = 1005;
int a[MAXN];

inline int lowbit(int x)
{
    return x & -x;
}

int main()
{
    int T; scanf("%d", &T);
    while (T--)
    {
        //input
        int n; scanf("%d", &n);
        for (int i = 0; i < n; i++) 
            scanf("%d", &a[i]);

        //sort
        sort(a, a + n);

        //main
        int maxValue = a[n-1] + a[n-2]; //找到最大值
        int maxLimit = maxValue;
        int ans = 0;

        //maxLimit = 小于等于maxValue的最大的2的n次方
        //例:若maxValue的二进制表示为11111,则maxLimit为10000
        //显然最终的答案一定属于[maxLimit, maxLimit << 1)
        while (maxLimit - lowbit(maxLimit) > 0) maxLimit -= lowbit(maxLimit); 

        //第一种情况
        //a[i]+a[j]属于[maxLimit, maxLimit << 1),但a[k]不属于该范围
        for (int i = n - 1; i > 0; i--)
        for (int j = i - 1; j >= 0; j--)
        {
            if (a[i] + a[j] < maxLimit) break;
            int sum = a[i] + a[j];
            int now = maxLimit, kl, kr, num = 0;
            //找到sum的第一个0的位置,该位置满足以下条件:
            //1.设这个位置为pos,即(1<>= 1;
                kl = lower_bound(a, a + n, now) - a;
                kr = lower_bound(a, a + n, now << 1) - a;
                for (int k = kl; k < kr; k++)
                {
                    if (k != i && k != j)
                    {
                        num++;
                        break;
                    }
                }
                now >>= 1;
            }
            //不存在上述位置的情况
            if (num == 0)
            {
            	//找到最小的位置且k != i && k != j
                int x = 0;
                if (x == j) x++;
                if (x == i) x++;
                //如果最小值为0
                if (a[x] == 0)
                {
                    if (sum > ans) ans = sum;
                }
                else
                {
                	//minLimit = 小于等于a[x]的最大的2的n次方
                	//则枚举的范围一定在[minLimit, minLimit << 1)之间
                    int minLimit = a[x];
                    while (minLimit - lowbit(minLimit) > 0) minLimit -= lowbit(minLimit);
                    minLimit <<= 1;
                    for (int k = x; k < n && a[k] < minLimit; k++)
                    {
                        if (k != i && k != j && (sum ^ a[k]) > ans) ans = sum ^ a[k];
                    }
                }
            }
            else
            {
            	//枚举寻找答案
                for (int k = kl; k < kr; k++)
                {
                    if (k != i && k != j && (sum ^ a[k]) > ans) ans = sum ^ a[k];
                }
            }
        }
        
        //另外一种情况
        //即a[k]属于[maxLimit, maxLimit << 1),但a[i]+a[j]不属于该范围
        for (int k = n - 1; k >= 0; k--)
        {
        	if (a[k] < maxLimit) break;
        	for (int i = 0; i < n; i++)
        	{
        		for (int j = i + 1; j < n; j++)
        		{
        			if (k != i && k != j && (a[k] ^ (a[i] + a[j])) > ans) ans = a[k] ^ (a[i] + a[j]);
        		}
        	}
        }
        printf("%d\n", ans);
    }
    return 0;
}


你可能感兴趣的:(hdu,acm,暴力)