hdu5491(2015合肥网络赛H题)
生活随笔
收集整理的這篇文章主要介紹了
hdu5491(2015合肥网络赛H题)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
給出三個數字D、s1和s2,用L來表示D的二進制表示中1的個數,L在區間[s1,s2]中,我們要找到離D最近的并且大于D的一個數字,且這個數字的L也落在區間[s1,s2]中。
思路:
一直超時。。。不知道為啥,后來也不知道為啥就不超時了。。。說說不超時的代碼。
對于一個數字D,我們先給它進行+1操作,看D+1是否滿足L值落在區間[s1,s2]中,如果滿足就輸出,不滿足就進行如下操作:
我們從最低位開始找,找到第一段連續的1,把這些1都變成0,然后把這些1的前面那個位置變成0,就如10111100110變成10111101000,然后我們要把最新得到的這個數的1的個數變成s1,從最低位開始補1就好了。
代碼:
#include <iostream> #include <cstdio> #include <cstring> using namespace std;long long G(long long n) {long long tmp = n - ((n >>1) &033333333333) - ((n >>2) &011111111111);return ((tmp + (tmp >>3)) &030707070707) %63; }int main() {long long t;long long d, s1, s2;scanf("%I64d",&t);for(long long kase = 1; kase <= t; kase++) {scanf("%I64d%I64d%I64d",&d,&s1,&s2);long long x = d + 1;long long num = G(x);if(num >= s1 && num <= s2) {printf("Case #%I64d: %I64d\n",kase,x);continue;}bool flag = false;for(long long i = 1; ; i <<= 1) {if(flag == false) {if((d & i)) {d -= i;flag = true;}} else {if((d & i)) {d -= i;flag = true;} else {d |= i;break;}}}x = d;num = G(x);if(num >= s1 && num <= s2);else x |= ((1 << (s1 - num)) - 1);printf("Case #%I64d: %I64d\n",kase,x);}return 0; }總結
以上是生活随笔為你收集整理的hdu5491(2015合肥网络赛H题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu5492(2015合肥网络赛I题)
- 下一篇: hdu5489(2015合肥网络赛F题)