對於二進位制每一位上的1進行考慮,2^0%3=1 , 2^1%3=2 , 2^2 %3=1 ,2^3 %3=2
那麼我們可以想到把a轉化為二進位制,然後他%3=1的位數有cnt1個,%3=2的位數有cnt2個。
我們可以想到每個數字最多由2個數字組成,下面給出證明。
那麼 sum=a%3,如果sum=0,那麼直接乙個數字帶走a了
如果sum=1:
那麼如果cnt1>0,那麼就把乙個%3=1的位數丟進ans[2]中,其他的位數就丟進ans[1]
否則由於輸入保證有解,那麼必有cnt2>=2,吧兩個%3=2的位數丟進ans[2],其他的丟進ans1
sum=2時
如果cnt2>0 , 1個%3=2->ans[2],否則必有cnt1>=2,。。。。
然後這樣ans[1]就處理完了,接下來我們要去找出一些已經進入ans[1]中的位數,讓ans[2]湊成3的倍數
由於此時ans[2]%3=1 or 2,而且必是剩餘2個1或者1個1或者兩個2或者1個2,而且保證有解。
那麼隨便找找就行了。
#include#define maxl 65
using namespace std;
long long top,anscnt;
long long a;
long long anum[maxl];
long long ans[3],mi[maxl];
bool in[maxl];
inline void prework()}
inline void mainwork()
long long cnt1=0,cnt2=0,sum=0,num1,num2;
for(long long i=1;i<=top;i++)
sum=cnt1+2*cnt2;
if(sum%3ll==1ll)
else
}else
else
}long long rescnt1=cnt1-num1,rescnt2=cnt2-num2;
anscnt=2;
ans[1]=0;ans[2]=0;
cnt1=0;cnt2=0;
for(long long i=1;i<=top;i++)
in[i]=false;
for(long long i=1;i<=top;i++)
}else}}
else
}else
}}}
inline void print()
int main()
return 0;
}
2019牛客多校第四場 A meeting
考場上寫了一大坨樹形dp,寫的時候就感覺我這不是跟求樹的最長鏈寫的一毛一樣 然後考後看題解,果然是k個ren所連成的子樹的最長鏈的一半 可以利用反證法證明,如果在長度為d的最長鏈的中間放乙個中心,如果有另外乙個點到這個點的長度 d 1 2,那麼這個點到對面的那個點的長度大於d,所以不存在這樣乙個點。...
2019牛客多校第四場A K
a.給你一張n個點n 1條邊的圖,和k個關鍵點。求乙個點到所有關鍵點距離最大值的最小為多少。乍一看像是對答案二分,但是考慮兩個相距最遠的關鍵點,假設他們的距離為d,那麼答案肯定為 d 1 2 如果有一點到中心點的距離超過了 d 1 2 那麼這個點會成為最遠關鍵點對中的乙個。矛盾。所以題目就變成了如何...
2019牛客多校第四場A meeting 思維
乙個樹上有若干點上有人,找出乙個集合點,使得所有人都到達這個點的時間最短 無碰撞 就是找樹的直徑,找直徑的時候記得要找有人的點 include include includeusing namespace std define pb push back define f first define s...