要麼三個都達到最大的數,要麼三個都到達最大的數+1,判斷是前一種狀況的方法是不斷墊高前兩大的,看以後最小的那個和最大的那個差值是否是2的倍數
不然就是第二種狀況ios
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <ctime> #include <vector> //#define ivorysi #define MAXN 100005 #define eps 1e-7 #define mo 974711 #define pb push_back #define mp make_pair using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; const int P = 100000; int a[5]; int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif for(int i = 1 ; i <= 3 ; ++i) scanf("%d",&a[i]); sort(a + 1,a + 4); if((a[3] - (a[1] + a[3] - a[2])) % 2 == 0) { printf("%d\n",a[3] - a[2] + (a[3] - (a[1] + a[3] - a[2])) / 2); } else { ++a[3];++a[1]; if(a[2] < a[1]) swap(a[2],a[1]); int cnt = 1 + a[3] - a[2] + (a[3] - (a[1] + a[3] - a[2])) / 2; printf("%d\n",cnt); } }
先二分一個答案,而後兩兩數乘積分個段的話是個二次函數,能夠三分求極值
WA了無數次,我實在不知道段該怎麼分,我把能分的部分都給取個max,而後過了函數
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <ctime> #include <vector> //#define ivorysi #define MAXN 100005 #define eps 1e-7 #define mo 974711 #define pb push_back #define mp make_pair using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; int64 A,B; int Q; int64 calc(int64 X,int64 MID) { int64 s = MID,t = X - MID + 2; if(s >= A) ++s; if(t <= B) --t; return s * t; } int64 get_Max(int64 X,int64 L,int64 R) { while(R - L + 1 >= 3) { int64 K = (R - L + 1) / 3; int64 LB = L + K,RB = R - K; if(calc(X,LB) < calc(X,RB)) L = LB; else R = RB; } int64 ans = 0; for(int64 i = L ; i <= R ; ++i) ans = max(ans,calc(X,i)); return ans; } int64 check(int64 MID) { int64 res = 0; res = max(get_Max(MID,1,A - 1),res); res = max(get_Max(MID,MID - A + 2,MID),res); res = max(get_Max(MID,1,B - 1),res); res = max(get_Max(MID,MID - B + 2,MID),res); res = max(get_Max(MID,A,B),res); res = max(get_Max(MID,A,MID - B + 2),res); res = max(get_Max(MID,B,MID - A + 2),res); return res; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif scanf("%d",&Q); while(Q--) { scanf("%lld%lld",&A,&B); if(A > B) swap(A,B); int64 P = A * B; int64 L = 0,R = (A + B); while(L < R) { int64 MID = (L + R + 1) >> 1; if(check(MID) < P) L = MID; else R = MID - 1; } printf("%lld\n",L); } }
顯然最後會Tozan最後不得不剩下一個A[i] > B[i]且B[i]最小的一塊,這是最優的
求個和減去這個B[i]就行spa
若是都相等就是0code
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <ctime> #include <vector> //#define ivorysi #define MAXN 200005 #define eps 1e-7 #define mo 974711 #define pb push_back #define mp make_pair using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; int64 A[MAXN],B[MAXN],sum; int N; int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif scanf("%d",&N); for(int i = 1 ; i <= N ; ++i) scanf("%lld%lld",&A[i],&B[i]); int64 minn = 0x7fffffff; for(int i = 1 ; i <= N ; ++i) { sum += B[i]; if(B[i] < A[i]) minn = min(B[i],minn); } if(minn == 0x7fffffff) puts("0"); else printf("%lld\n",sum - minn); }
若是s中每一個數都相等,那麼答案是1orm
若是s<=3暴搜遞歸
以後咱們發現若是a = 0,b = 1,c = 2
那麼變換後的串和原來的串總和是同樣的
並且變換後的串裏面必定有兩個相鄰數字是同樣的get
如何證實呢,咱們把長度爲4的狀況暴搜一下,發現是對的,而後之後長度的狀況就能夠把第一個字符改爲對的而後刪掉第一個字符遞歸證實string
而後用一個dp求出這樣的串,同時若沒有兩個相鄰數字是同樣的,還要檢查一下S自己是否是一個這樣的串it
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <ctime> #include <vector> //#define ivorysi #define MAXN 200005 #define eps 1e-7 #define mo 974711 #define pb push_back #define mp make_pair using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; const int64 MOD = 998244353; int N; char s[MAXN]; int64 dp[MAXN][3][3][2]; void inc(int64 &x,int64 y) { x = x + y; while(x >= MOD) x -= MOD; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif scanf("%s",s + 1); N = strlen(s + 1); bool all_same = 1; for(int i = 1 ; i <= N ; ++i) { if(s[i] != s[1]) all_same = 0; } if(all_same) {puts("1");return 0;} if(N > 3) { for(int i = 0 ; i <= 2 ; ++i) dp[1][i][i][0] = 1; for(int i = 2 ; i <= N ; ++i) { for(int s = 0 ; s <= 2 ; ++s) { for(int j = 0 ; j <= 2 ; ++j) { for(int h = 0 ; h <= 2 ; ++h) { for(int l = 0 ; l <= 1 ; ++l) { inc(dp[i][(s + h) % 3][h][l || h == j],dp[i - 1][s][j][l]); } } } } } bool flag = 1; int c = 0; for(int i = 1 ; i <= N ; ++i) { c = (c + s[i] - 'a') % 3; } for(int i = 2 ; i <= N ; ++i) { if(s[i] == s[i - 1]) {flag = 0;break;} } int64 ans = flag; for(int i = 0 ; i <= 2 ; ++i) ans += dp[N][c][i][1]; ans %= MOD; printf("%lld\n",ans); } else { if(N == 3) { if(s[1] != s[2] && s[2] != s[3] && s[1] != s[3]) puts("3"); else if(s[1] == s[2] || s[2] == s[3]) puts("6"); else puts("7"); } else if(N == 2) { puts("2"); } } return 0; }