Best cattle fence
code:
#include<stdio.h> #include<iostream> #include<math.h> #include<algorithm> using namespace std; const int N = 1e5 + 10; const double eps = 1e-5; double a[N],b[N],sum[N]; int n,f; int main(){ scanf("%d%d",&n,&f); for(int i = 1 ;i<=n;++ i)scanf("%lf",&a[i]); double L = -1e6 , r = 1e6; // Binary average while(L + eps < r ){ double mid = (L + r)/2; // Whether the average number in the length of this section is greater than mid will become whether the sum of this section is greater than 0 after subtracting mid for(int i = 1;i<= n ;++i) b[i] = a[i] - mid; // Prefix Sum for(int i = 1;i<=n;++i) sum[i] = sum[i-1] + b[i]; double ans = -1e10; double min_val = 1e10; for(int i = f;i<=n;++i){ min_val = min(min_val,sum[i-f]); ans = max(ans,sum[i] - min_val); } if(ans >=0) L = mid; else r = mid; } cout<<int(r*1000)<<endl; return 0; }Discretization
film
Problem solving ideas:
This topic is a good discretization topic, because the languages here are very scattered, so we can bring them together, that is, redefine these languages and label them 1,2,3,..., n1,2,3,..., n.
In terms of statistics, because the time limit is very strict, the hash level map of C++11 is used,
code:
#include<iostream> #include<stdio.h> #include<map> #include<algorithm> using namespace std; const int N = 2e5 + 10; int n,m; map<int,int>lg; int a[N] ,b[N] ,ans[N]; int main() { scanf("%d",&n); for(int i= 1;i<= n ;++i){ int x; scanf("%d",&x); lg[x]++; } scanf("%d",&m); for(int i=1;i<=m;++i) scanf("%d",&a[i]); for(int i=1;i<=m;++i) scanf("%d",&b[i]); int maxx = 0; for(int i=1;i<=m;++i) maxx = max(maxx,lg[a[i]]); //Get the largest number of people who can speak the language int k = 0; for(int i=1;i<=m;++i) if(lg[a[i]] == maxx) // Through this number, you can find the number of movies inside and save it in the array ans[k++] = i; if(k == 1) // If there is only one field, output it directly printf("%d\n",ans[0]); else{ int res = 0,pos = 0; for(int i = 0;i<k;++i) // Otherwise, in these movies, find the movie number that makes you happy. If it is the same, choose the later one if(lg[b[ans[i]]] >= res){ res = lg[b[ans[i]]]; pos = ans[i]; } printf("%d\n",pos); } return 0; }median
Warehouse location
Problem solving ideas;
Sort + median
The median has excellent properties. For example, in this topic, the distance from each point to the median satisfies the global optimality rather than the local optimality.
Specifically, we set all points on the left of the warehouse. The sum of the distances to the warehouse is pp and the sum of the distances on the right is qq. Then we must make the value of p+qp+q as small as possible.
When the warehouse moves to the left, pp will decrease by xx, but qq will increase by n − xn − x, so when it is the median warehouse, p+qp+q is the smallest.
In the same sentence, drawing understanding is very important.
First look at the two points
Analogy to n
code:
#include<stdio.h> #include<algorithm> using namespace std; const int N = 1e5 + 10; int n,a[N]; long long ans; int main(){ scanf("%d",&n); for(int i = 1; i <= n;++i) scanf("%d",&a[i]); sort(a+1,a+1+n); int pos ; if(n&1) pos = (n+1)>>1; else pos = n >>1; ans = 0; for(int i = 1;i<= n;++i) ans += abs(a[i] - a[pos]); printf("%lld\n",ans); return 0; }
Dynamic median
Problem solving ideas:
skill:
- Large root pile and small root pile
priority_queue<int> down; //Big root pile priority_queue<int, vector<int>, greater<int>> up; //Small root pile
- The number of odd positions in n numbers and the middle position.
Unity can be written as: (n + 1) > > 1
code:
#include<stdio.h> #include<algorithm> #include<vector> #include<queue> using namespace std; int t,T,id,n; // Take the top of the large root heap as the median int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&id,&n); printf("%d %d\n",id,(n+1)>>1); int cnt = 0; priority_queue<int> down; //Big root pile priority_queue<int, vector<int>, greater<int>> up; //Small root pile for(int i=1;i<=n;++i){ int x; scanf("%d",&x); // If the large root heap is empty or the current value is less than or equal to the median, insert the large root heap if(down.empty() || x<= down.top()) down.push(x); else up.push(x);//If not, insert the small root heap // Because it is a large root heap and the top of the heap is the median, under normal circumstances, the number of large root heaps should be the number of small root heaps + 1 // So if it is larger than up.size() + 1, put the top on the small root heap if(down.size() > up.size() + 1) // The number of small heel piles is less than 1, so it is more if it is equal to if(up.size() > down.size()) { down.push(up.top()) , up.pop(); } if(i&1){ printf("%d ",down.top()); if(++cnt % 10 == 0)putchar('\n'); } } if(cnt %10) putchar('\n'); } return 0; }Reverse order pair
definition
For a sequence a, if
KaTeX parse error: Expected 'EOF', got '&' at position 6: i<j &̲& a[i] > a[j] ,...
Using merge sort to find
code:
// left = 1, right = n; void msort(int left , int right){ if(left == right)return ; int mid = (left + right) >>1,i,j,k; msort(left,mid),msort(mid+1,right); k = left; for( i = left,j = mid+1;i<=mid && j<=right;){ if(a[i]<=a[j]) b[k++] = a[i++]; else b[k++] = a[j++] , ans += mid - i + 1; // It shows that the second half has a smaller size than the first half // i is the number of the first half of the comparison, that is, it is greater than the second half // The number is the distance from it to the middle. } while(i<=mid)b[k++] = a[i++]; while(j<=right) b[k++] = a[j++],ans += mid-i+1; // printf("ans %d \n",ans); for( i = left;i<=right;++i) a[i] = b[i]; }
Odd number problem
The conclusions of such topics are as follows:
When n is odd
If and only if the numbers in the grid in the two situations are written into a sequence of n*n-1 elements in a row, regardless of spaces, the parity of the reverse pairs can be the same.
When n is even
If and only if the numbers in the grid in the two situations are written into a sequence of n*n-1 elements in a row, the parity of "difference of reverse logarithm" and "difference of rows of spaces in the two situations" can be the same regardless of spaces.
code:
#include<stdio.h> #include<algorithm> #include<cstring> const int N = 3e5 + 10; int n,a[N],b[N]; long long cnt1 , cnt , ans; void msort(int left , int right){ if(left == right)return ; int mid = (left + right) >>1,i,j,k; msort(left,mid),msort(mid+1,right); k = left; for( i = left,j = mid+1;i<=mid && j<=right;){ if(a[i]<=a[j]) b[k++] = a[i++]; else b[k++] = a[j++] , ans += mid - i + 1; // It shows that the second half has a smaller size than the first half // i is the number of the first half of the comparison, that is, it is greater than the second half // The number is the distance from it to the middle. } while(i<=mid)b[k++] = a[i++]; while(j<=right) b[k++] = a[j++],ans += mid-i+1; // printf("ans %d \n",ans); for( i = left;i<=right;++i) a[i] = b[i]; } int main(){ while(~scanf("%d",&n)){ int ok = 0,x; // Don't add 0 for(int i=1;i<=n*n;++i) { scanf("%d",&x); if(!x) ok = 1; else a[i-ok] = x; } ans = 0 , memset(b,0,sizeof b); msort(1,n*n); cnt = ans , memset(b,0,sizeof b),ok = 0; memset(a,0,sizeof a); // Because the position of 0 may be different, it should be cleared for(int i=1;i<=n*n;++i) { scanf("%d",&x); if(!x) ok = 1; else a[i-ok] = x; } ans = 0,msort(1,n*n); //printf("%d %d\n",cnt,ans); if((cnt & 1) == (ans & 1) ) // Remember to add parentheses, & operations are smaller than = = printf("TAK\n"); else printf("NIE\n"); } return 0; }