[JZOJ4274] [NOIP2015模拟10.28B组] 终章-剑之魂 解题报告(二进制)
生活随笔
收集整理的這篇文章主要介紹了
[JZOJ4274] [NOIP2015模拟10.28B组] 终章-剑之魂 解题报告(二进制)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
【背景介紹】古堡,暗鴉,斜陽,和深淵……
等了三年,我獨自一人,終于來到了這里……
“終焉的試煉嗎?就在這里嗎?”我自言自語道。
“終焉的試煉啊!就在這里啊!”我再一次自言自語道。
“這背后可能有那個東西嗎?”我自言自語道。
“這背后一定有那個東西呢!”我又一次自言自語道。
我沉默著,踏上黑漆漆的索橋,小心翼翼地,拿出鋒利的注入我靈魂的雙劍……
“那么,我們開始吧……”我最后一次自言自語道。 【題目描述】
My?soul?of?my?sowrd!
終焉的試煉即將到來,作為一名有修養的劍士,雖然沒有習得n刀流但是二刀流還是沒問題的。然而我也是個劍的收藏者,家里屯著n把劍,每一把劍都有一個靈魂值a[i],由于一些劍之間可能有共鳴,所以我需要兩把契合度最高的劍。據劍圣所說,兩把編號為i,j劍的契合度為a[i]?and?a[j]。如何深得劍的靈魂呢?
注:AND?為按位與運算,先將數轉成二進制,不滿位數的補全0,然后成為兩個長度相同的二進制數,處理的時候,兩個相應的二進制位都為1,該位的結果值才為1,否則為0。例下圖。
?
Input
第一行一個整數n,代表藏劍數。第二行n個整數,第i個整數表示a[i]。
Output
輸出包含一個正整數,最好的兩把劍的契合度。Sample Input
512?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
?
題目大意:給定n個數,從中挑選兩個數進行&(and)運算,最大化&值并輸出
題解:采取二進制高位到低位的貪心策略,即從高到低能變成1就變成1
那我們就考慮答案的倒數第i位是否可以選。
設當前ans為比第i位高的所有二進制位選擇的最優情況的和,那么如果第i位能選,就必定在這n個數中至少有兩個數滿足:
1.當前答案中的所有二進制為1的位置,在相應的這個數中的位置也為1(即ans&a==ans);
2.這個數的二進制第i位為1(即a&(2^(i-1)==(2^(i-1)))。
所以,我們只需從高位向低位掃一遍就可以了。
時間:O(30*n)
空間:n
還有不懂的讀者手推即可
#include<iostream> #include<cstdio> #include<algorithm> using namespace std;const int maxn=1e6+50; int n,ans; int a[maxn]; inline int read() {char ch=getchar();int s=0,f=1;while (!(ch>='0'&&ch<='9')) {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}return s*f; } int main() {freopen("sword.in","r",stdin);freopen("sword.out","w",stdout);n=read();for (int i=1;i<=n;i++)a[i]=read();for (int i=31;i>=0;i--){int p=0;for (int j=1;j<=n;j++){if ((ans&a[j])==ans&&(a[j]&(1<<i))) p++;if (p>=2) break;}if (p>=2) ans+=1<<i;}printf("%d\n",ans);return 0; }?
轉載于:https://www.cnblogs.com/xxzh/p/9302982.html
總結
以上是生活随笔為你收集整理的[JZOJ4274] [NOIP2015模拟10.28B组] 终章-剑之魂 解题报告(二进制)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux云计算【第一阶段】第十二章:网
- 下一篇: 词袋模型 matlab,【火炉炼AI】机