20200724T3 【NOIP2015模拟10.28B组】终章-剑之魂 Description Input Output Sample Input Sample Output Data Constraint solution rethink code

【背景介绍】

古堡,暗鸦,斜阳,和深渊……
等了三年,我独自一人,终于来到了这里……
“终焉的试炼吗?就在这里吗?”我自言自语道。
“终焉的试炼啊!就在这里啊!”我再一次自言自语道。
“这背后可能有那个东西吗?”我自言自语道。
“这背后一定有那个东西呢!”我又一次自言自语道。
我沉默着,踏上黑漆漆的索桥,小心翼翼地,拿出锋利的注入我灵魂的双剑……
“那么,我们开始吧……”我最后一次自言自语道。

【题目描述】

My soul of my sowrd!
终焉的试炼即将到来,作为一名有修养的剑士,虽然没有习得n刀流但是二刀流还是没问题的。然而我也是个剑的收藏者,家里屯着n把剑,每一把剑都有一个灵魂值a[i],由于一些剑之间可能有共鸣,所以我需要两把契合度最高的剑。据剑圣所说,两把编号为i,j剑的契合度为a[i] and a[j]。如何深得剑的灵魂呢?
注:AND 为按位与运算,先将数转成二进制,不满位数的补全0,然后成为两个长度相同的二进制数,处理的时候,两个相应的二进制位都为1,该位的结果值才为1,否则为0。例下图。

20200724T3 【NOIP2015模拟10.28B组】终章-剑之魂
Description
Input
Output
Sample Input
Sample Output
Data Constraint
solution
rethink
code

Input

第一行一个整数n,代表藏剑数。
第二行n个整数,第i个整数表示a[i]。

Output

输出包含一个正整数,最好的两把剑的契合度。

Sample Input

5
12 5 6 3 1

Sample Output

4
【样例解释】
5 and 6=4或者12 and 5=4或者12 and 6=4

Data Constraint

对于40%的数据 n ≤ 1,000
对于100%的数据 n ≤ 1,000,000,0 ≤ a[i] < 2^31

solution

对于40%的数据

时间复杂度:20200724T3 【NOIP2015模拟10.28B组】终章-剑之魂
Description
Input
Output
Sample Input
Sample Output
Data Constraint
solution
rethink
code

直接暴力两两判断

对于100%的数据

1.先sort然后前后两两判断

时间复杂度:20200724T3 【NOIP2015模拟10.28B组】终章-剑之魂
Description
Input
Output
Sample Input
Sample Output
Data Constraint
solution
rethink
code

 显然错误,但是数据太水了。。。

2.暴力基础上用ans优化

还是数据太水了。。。

正解

先考虑答案性质:

  Ans=a1*2^0+a2*2^1+a3*2^a3+…….+an*2^(n-1);

可见答案中吗,高位的肯定比不选优

我们就考虑答案的倒数第i位是否可以

设当前Ans为比第i位高的所有二进制位选择的最情况的和,那么如果第i位能选,必定在这n个数中至少有两个数满足:

1:当前答案中的所有二进制为1位置在相应的这个数的位置也为1(ans and a=ans);

2:这个数的二进制i位1(即a and (2^(i-1)=(2^(i-1))

所以我们只需从高位低位扫一就可以了。

时间O(30*n)

空间n

rethink

对二进制还是不够熟练

大致思路没问题

但是WA了两个点

看到数据这么水我都怀疑我是不是错的。。。

 1 void violence()
 2 {
 3     for(R int i = 1; i <= n; i++) read(a[i]);
 4     for(R int i = 1; i <= n; i++)
 5         for(R int j = i + 1; j <= n; j++)
 6             ans = max(ans, a[i] & a[j]);
 7     writeln(ans);
 8 }
 9 bool cmp(int a, int b)
10 {
11     return a > b;
12 }
13 int count(int x)
14 {
15     int k = 0;
16     while(x)
17     {
18         k++;
19         x >>= 1;
20     }
21     return k;
22 }
23 int and1(int x)
24 {
25     return ((1 << x) - 1);
26 }
27 void work()
28 {
29     for(R int i = 1; i <= n; i++) read(a[i]);
30     do
31     {
32         sort(a + 1, a + n + 1, cmp);
33         int ii = 1;
34         while(count(a[ii]) != count(a[ii + 1]) && ii + 1 <= n) ii++;
35         //printf("%lld
",ii);
36         if(ii != 1)
37         {
38             int qwq = count(a[ii]);
39             //writeln(qwq);
40             int cut = and1(qwq);
41             for(R int i = 1; i <= ii - 1; i++) a[i] = a[i] & cut;
42             //for(R int i = 1; i <= n; i++) writesn(a[i]);
43             //putchar('
');
44             //writeln(n);
45             continue;
46         }
47         int k = count(a[1]);
48         for(R int i = 3; i <= n; i++) 
49             if(count(a[i]) != k)
50             {
51                 n = i - 1;
52                 break;
53             }
54         book[k] = 1;
55         for(R int i = 1; i <= n ; i++) a[i] -= (1 << (k - 1));
56     }while(a[1]);
57     for(R int i = 1; i <= 31; i++) if(book[i]) ans += (1 << (i - 1));
58     writeln(ans);
59 }
60 signed main()
61 {
62     //freopen("sword.in","r",stdin);
63     //freopen("sword.out","w",stdout);
64     read(n);
65     if(n <= 5000)
66     {
67         violence();
68         return 0;
69     }
70     work();
71     return 0;
72 }

code

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<queue>
 7 #include<vector>
 8 #include<stack>
 9 #include<set>
10 #include<deque>
11 #include<map>
12 using namespace std;
13 
14 template <typename T> void read(T &x) {
15     x = 0; int f = 1; char c;
16     for (c = getchar(); c < '0' || c > '9'; c = getchar()) if (c == '-') f = -f;
17     for (; c >= '0' && c <= '9'; c = getchar()) x = 10 * x + c - '0' ;
18     x *= f;
19 }
20 template <typename T> void write(T x){
21     if (x < 0) putchar('-'), x = -x;
22     if (x > 9) write(x / 10);
23     putchar(x % 10 + '0');
24 }
25 template <typename T> void writeln(T x) { write(x); putchar('
'); }
26 template <typename T> void writesn(T x) { write(x); putchar(' '); }
27 
28 #define ll long long
29 #define inf 1234567890
30 #define next net
31 #define P 2147483647
32 #define N 1000010
33 #define mid ((l+r)>>1)
34 #define lson (o<<1)
35 #define rson (o<<1|1)
36 #define R register
37 #define debug puts("zxt")
38 
39 int n, ans;
40 int a[1000010];
41 signed main()
42 {
43     //freopen("sword.in","r",stdin);
44     //freopen("sword.out","w",stdout);
45     read(n);
46     for(R int i = 1; i <= n; i++) read(a[i]);
47     for(R int i = 31; i >= 1; i--)
48     {
49         int t = 0;
50         for(R int j = 1; j <= n; j++)
51             if(((ans & a[j]) == ans) && ((a[j] & (1 << (i - 1))) != 0)) t++;
52         if(t >= 2) ans += (1 << (i - 1));
53     }
54     writeln(ans);
55     return 0;
56 }