10.28 訓練題題解
阿新 • • 發佈:2020-10-28
CodeForces 550B Preparing Olympiad
題目大意:給出n個數字,要求在這n個數中選出至少兩個數字,使得它們的和在l,r之間,並且最大的與最小的差值要不小於x。
解題思路:因為題目給出的n=15,直接二進位制暴力列舉所有的狀況即可。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<iostream> 7 #include<vector> 8#include<set> 9 #include<queue> 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 typedef long long int ll; 13 const int N = 1e5 + 100; 14 ll n, l, r, x; 15 ll arr[N]; 16 int main() { 17 cin >> n >> l >> r >> x; 18 int ans = 0; 19 for (int i = 0;i < n;i++)cin >> arr[i];20 sort(arr , arr + n);//排序方便後面比較差值是否大於等於x 21 for (int i = 0;i < (1 << n);i++) { 22 vector<int>v; 23 ll sum = 0; 24 for (int j = 0;j <n;j++) { 25 if ((i>>j)&1)v.push_back(arr[j]), sum += arr[j]; 26 } 27 int sz = v.size();28 if (sz < 2)continue;//如果vector中的元素<2直接忽略 29 if (sum >= l && sum <= r && (v[sz - 1] - v[0] >= x))ans++; 30 } 31 cout << ans << endl; 32 }
CodeForces 535C Tavas and Karafs
題意大意:給你一個首項為A,公差為B的等差數列,再給你一個N代表有N次詢問,每次詢問會有三個值L,T,M代表在經過T次操作之後以L為左端點的等於0的串最長能有多長。
每一次操作是使任意M個不為0的數字的值都減一。
解題思路:若S(l)的值大於t,無法滿足題意,直接輸出 -1;否則的話,如果滿足t*m要>=S(l)至S(r)的和,則滿足題意。那麼根據這個條件對右端點進行二分查詢即可。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<iostream> 7 #include<vector> 8 #include<set> 9 #include<queue> 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 typedef long long int ll; 13 const int N = 1e5 + 100; 14 ll a, b, n; 15 ll L, t, m; 16 ll f(ll x) { 17 return a + (x - 1) * b; 18 } 19 bool solve(ll mid) { 20 ll n=mid-L+1; 21 return n*f(L)+n*(n-1)*b/2 <=t*m; 22 //Sn=n*a1+(n-1)*n*d/2等差數列求和公式 23 } 24 int main() { 25 cin >> a >> b >> n; 26 while (n--) { 27 cin >> L >> t >> m; 28 if (f(L) > t) { 29 puts("-1");continue; 30 } 31 //因為右端點的值一定小於等於t,所以a+(r-1)*b<=t ,r<(t-a)/b+1 32 ll l = 1, r = (t - a) / b + 1, mid; 33 ll ans; 34 while (r >= l) { 35 mid = l + r >> 1; 36 if (solve(mid))l = mid + 1, ans = mid; 37 else r = mid - 1; 38 } 39 cout << ans << endl; 40 } 41 }
HDU5705 CLOCK
題目大意:給出時間 HH:MM:SS 角度a 問下一個H和M的角度為a的時刻。
解題思路:首先知道時針120秒走1度,分針10秒走一度。故120秒分針和時針相差11度,所以相差一度需要120/11秒,考慮到精度可以讓所有的資料乘以11變成整數。時間從120秒開始列舉,直到滿足條件結束, 由於前面乘以了11,結果需要除以11。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<iostream> 7 #include<vector> 8 #include<set> 9 #include<queue> 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 typedef long long int ll; 13 const int N = 1e5 + 100; 14 int main() { 15 int hh, mm, ss, a, cnt = 0; 16 while (scanf("%d:%d:%d", &hh, &mm, &ss) != EOF) { 17 scanf("%d", &a); 18 int t = hh * 3600 + mm * 60 + ss;//計算出當前時刻 單位是秒 19 t *= 11;a *= 11; 20 int angle = 0, now_angle = 0; 21 int st = 120; 22 while (1) { 23 angle += 11; 24 if (angle > 360 * 11) now_angle = angle % (11 * 360);//超過1圈就取餘 25 else now_angle = angle; 26 if (now_angle > 180 * 11) now_angle = 360 * 11 - now_angle;//分鐘和時針的夾角,大於180,轉換為180以內。 27 if (now_angle == a && st > t) break;//度數相同且時間大於原來的時間 28 st += 120; 29 } 30 st %= 43200 * 11; 31 int h = st / (3600 * 11); 32 int m = (st - h * (3600 * 11)) / (60 * 11); 33 int s = (st - h * (3600 * 11) - m * (60 * 11)) / 11; 34 if (h == 24) h = 0; 35 printf("Case #%d: %02d:%02d:%02d\n", ++cnt, h, m, s); 36 } 37 }