1. 程式人生 > >POJ-3484 Showstopper---二分+前綴和

POJ-3484 Showstopper---二分+前綴和

奇數 font 鏈接 target mes continue per code +=

題目鏈接:

https://cn.vjudge.net/problem/POJ-3484

題目大意:

給出一系列等差數列,給出第一項和最後一項和公差

這些等差數列中每個數出現的次數只有一個是奇數,找出這個數,並求出其出現的次數

解題思路:

二分枚舉這個數,但是只是二分這個數字的話,找不到二分的條件。

所以枚舉判斷的時候,求出小於等於這個數字的數有多少個,如果是奇數個,說明該數 >= 解

如果是偶數,該數 < 解

輸入很坑,數據與數據之間可能有多個空行

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4
5 using namespace std; 6 typedef long long ll; 7 const int maxn = 1e7 + 10; 8 const double eps = 1e-5; 9 struct node 10 { 11 ll l, r, d; 12 }a[maxn]; 13 int n; 14 bool read() 15 { 16 bool ok = 0; 17 n = 0; 18 char s[100]; 19 while(gets(s)) 20 { 21 if(strlen(s) == 0) 22
{ 23 if(ok)break; 24 continue; 25 } 26 ok = 1; 27 sscanf(s, "%lld%lld%lld", &a[n].l, &a[n].r, &a[n].d); 28 n++; 29 } 30 return ok; 31 } 32 ll judge(ll mid) 33 { 34 ll tot = 0; 35 for(int i = 0; i < n; i++) 36
{ 37 if(mid < a[i].l)continue; 38 if(mid > a[i].r) 39 tot += (a[i].r - a[i].l) / a[i].d + 1;//註意加一,兩種情況都需要加一 40 else 41 { 42 tot += (mid - a[i].l) / a[i].d + 1; 43 } 44 } 45 return tot; 46 } 47 int main() 48 { 49 while(read()) 50 { 51 ll l = 1, r = 1LL << 33, ans = 0; 52 while(l <= r) 53 { 54 ll mid = (l + r) / 2; 55 //cout<<mid<<" "<<judge(mid)<<endl; 56 if(judge(mid) & 1) 57 { 58 ans = mid; 59 r = mid - 1; 60 } 61 else l = mid + 1; 62 } 63 if(ans == 0) 64 { 65 printf("no corruption\n"); 66 continue; 67 } 68 ll tot = 0; 69 for(int i = 0; i < n; i++) 70 { 71 if(ans >= a[i].l && ans <= a[i].r && ((ans - a[i].l) % a[i].d == 0))tot++; 72 } 73 printf("%lld %lld\n", ans, tot); 74 } 75 return 0; 76 }

POJ-3484 Showstopper---二分+前綴和