Contents
- Contents
- Six tuples
- Description
- Input
- Output
- Data scope and conventions
- Solution
- Cattle sort
- Description
- Input
- Output
- Sample explanation
- Solution
- Playing Bricks
- Description
- Input
- Output
- Data scope and conventions
- Solution
1. Six tuples
(Six.c/.cpp/.pas)
Description
There are n integers, and now you want to know how many six tuples (a,b,c,d,e,f)
Satisfying: (AXB + c) ÷d–e = f
Input
The input file name is (six.in).
First line: N (1<=n<=10)
Second row n number ai ( -30000<=ai<=30000)
Output
The output file name is (six.out).
The number of such six-tuple outputs
2
2 3 4
Data scope and conventions
For 30% of data, 1 <= n <= 10
For 100% of data, 1 <= n <= 100
Solution:
At first I thought test instructions was: Given AI is a, so to find the b,c,d,e,f that satisfies all AI
Ghosts can make it.
Finally only to clarify the test instructions, A,b,c,d,e,f is the number of n any one, as long as the requirements are good. This makes it very simple. But look at the data range to know that six-dimensional enumeration can only get 30 points, and to think of 100 points must be pressed to at most three-dimensional. But this is not a hassle, and simplifying can get
a*b+c=d* (e+f), you can enumerate three numbers a[i],a[j],a[k] at the same time. If the number on the left of the equation is placed in the array l[], and the right is placed in r[], if a number in l[] appears in r[], the cumulative number is the last answer.
However, it is important to note that it is not possible to enumerate directly, so that the tle can be used in the STL map or multiset, but it turns out that the latter is not OK. Also timed out. Here are the code for the two methods:
Code1 "Map":
#include <stdio.h>#include <string.h>#include <map>#define MAXN 1001000typedef Long Longllusing namespace STD;intN,ans;inta[ the],L[MAXN],R[MAXN]; map<int,int>mpintMain () {Freopen ("Six.in","R", stdin); Freopen ("Six.out","W", stdout);scanf("%d", &n); for(intI=1; i<=n;i++) {scanf("%d", &a[i]); } for(intI=1; i<=n;i++) { for(intj=1; j<=n;j++) { for(intk=1; k<=n;k++) {mp[a[i]*a[j]+a[k]]++; } } } for(intI=1; i<=n;i++) {if(!a[i])Continue; for(intj=1; j<=n;j++) { for(intk=1; k<=n;k++) {intx=a[i]* (A[j]+a[k]); ANS+=MP[X]; } } }printf("%d\n", ans);return 0;}
Code2: "Multiset"
#include <stdio.h>#include <string.h>#include <set>#define MAXN 1001000typedef Long Longllusing namespace STD; ll N,ans;ll a[ the],L[MAXN],R[MAXN]; multiset<int>SintMain () {Freopen ("Six.in","R", stdin); Freopen ("Six.out","W", stdout);scanf("%lld", &n); for(LL i=1; i<=n;i++) {scanf("%lld", &a[i]); } ll Cnt_l=0, cnt_r=0; for(LL i=1; i<=n;i++) { for(LL j=1; j<=n;j++) { for(LL k=1; k<=n;k++) {S.insert (a[i]*a[j]+a[k]); } } } for(intI=1; i<=n;i++) { for(intj=1; j<=n;j++) { for(intk=1; k<=n;k++) {ll x=a[i]* (a[j]+a[k]);if(S.count (x)! =0) {Ans+=s.count (x); } } } }printf("%lld\n", ans);return 0;}
2. Cattle sorting
(Cowsort.c/.cpp/.pas)
Description
Farmer John is ready to queue his n (1 <= n <= 10,000) cows for action. Because a big-tempered bull could be disruptive, John wanted to sort the cows by the size of their temper. Each cow's temper is an integer between 1 and 100,000 and no two cows have the same temper value. During the sorting process, John can swap the positions of any two cows. Because the big-tempered cows are not moving, John needs x+y seconds to exchange two cows with a temper value of x and Y.
Please help John calculate the shortest time to order all the steaks.
Input
The input file name is (cowsort.in).
Line 1th: a number n.
Line 2~n+1: One number per line, and line i+1 is the temper value of the first cow.
Output
The output file name is (cowsort.out).
Line 1th: A number that puts all steaks in good order for the shortest time.
3
2
3
1 7
Sample explanation
There were three cows in the queue, with a temper of 2, 3, and 1.
2 3 1: Initial sequence
2 1 3: Exchange temper for the cattle of 3 and 1 (Time =1+3=4).
1 2 3: Exchange temper for the cattle of 1 and 2 (Time =2+1=3).
Solution:
At first I thought the problem was like a quick platoon, then I wrote a quick line and then added a change of temper value. But if you think about it, this only maintains the least number of exchanges, but not necessarily the total value and minimum of the exchange.
Alas (????)??, or introduce a positive solution:
It is divided into 4 steps:
STEP1:
Example
| 8 4 5 3 2 7 |
1 8 9) 7 6 |
| 2 3 4 5 7 8 |
1 6 7) 8 9 |
The first step, very simple ~ separate order.
STEP2:
It can be felt that (3 4 5) (8 2 7) is the first set of data two cycles, (1) (8 9 7 6) is the second set of data two cycles. The scientific name is called permutation group (so better understanding?) )
So our second step is to find the so-called permutation group .
STEP3:
usually in a loop, it is best to replace all the remaining numbers with Min. The total cost is:
sum-min+ (len-1) *min=>sum+ (len-2) *min;
STEP4:
However, such as 1 8 9 7 6 The above method is not established, instead of making (1) a separate group, replace the 6. That is (6) (1 8 9 7) The cost is sum+min+ (len-1) *smallest;
So for each cycle, ans+=min{sum+ (len-2) *min, sum+min+ (len-1) *smallest}
Code:
#include <stdio.h>#include <string.h>#include <algorithm>#define INF 9999999#define MAXN 1000000Using namespace Std;struct node{intLenintMiintsum;} CIR[MAXN];intN,cnt,ans;intA[MAXN],TMP[MAXN],POS[MAXN],VISIT[MAXN];intcmpintAintb) {returnA<b?1:0;}intMinintAintb) {returnA<B?A:B;} void Pre_init () { for(intI=1; i<=n;i++) {cir[i].mi=inf; }}intFindint x){intL=1, R=n; while(L<r) {intMid= (l+r) >>1;if(tmp[mid]>=x) {R=mid; }ElseL=mid+1; }returnR;}intMain () {//freopen("Cowsort.in","R", stdin);//freopen("Cowsort.out","W", stdout); scanf"%d", &n); Pre_init (); for(intI=1; i<=n;i++) {scanf ("%d", &a[i]); Tmp[i]=a[i]; }Sort(tmp+1, tmp+1+N,CMP); for(intI=1; i<=n;i++) {POS[I]=find (A[i]); } for(intI=1; i<=n;i++) {if(!visit[i]&&a[i]!=tmp[i]) {visit[i]=1, cir[++cnt].len=1; Cir[cnt].sum+=a[i]; Cir[cnt].mi=min (Cir[cnt].mi,a[i]);intt=i; while(a[POS[t]]! =a[i]) {t=POS[t];visit[t]=1; Cir[cnt].len++;cir[cnt].sum+=a[t];cir[cnt].mi=min (Cir[cnt].mi,a[t]); } } } for(intI=1; i<=cnt;i++) {intt1=cir[i].sum+ (cir[i].len-2)*cir[I].MI;intt2=cir[i].sum+cir[i].mi+ (cir[i].len+1)*tmp[1]; Ans+=min (T1,T2); }printf("%d\ n", ans);return 0;}
3. Playing Bricks
(Brike.c/.cpp/.pas)
Description:
N-layer bricks are placed in a groove, the top layer has n blocks, the second layer has n-1 blocks, ..., and the bottom layer has only one brick. The bricks on layer I are numbered from left to right and 1,2,......,i, and block J of Layer I has a value a[i,j] (a[i,j]<=50). Here is an example of a 5-storey brick:
If you want to knock off the first layer of block J brick, if i=1, you can directly knock it off, if i>1, you must first knock off the i-1 layer of the section J and j+1 block bricks.
Your task is to knock off (m<=500) bricks from a heap of bricks with N (n<=50) so that the value of the bricks knocked out is the largest sum.
Input:
The input file name is (brike.in).
The first behavior two positive integers, respectively, represents N,m, the next I each row has n-i+1 data, respectively represents A[i,1],a[i,2]......a[i,n–i + 1].
Output:
The output file name is (brike.out).
There is only one positive integer that represents the sum of the maximum value of the bricks being knocked off.
4 5
2 2 3 4
8 2 7
2 3
49 19
Data scope and conventions
For 20% of data, meet 1≤n≤10,1≤m≤30
For 100% of data, meet 1≤n≤50,1≤m≤500
Solution:
Direct adhesive:
found that the same row can be knocked out of the bricks can be irregular distribution, but each column can only be knocked down from the top down continuous brick, so consider following each column DP.
Design status F[i][j][k] means hit to the forexample, the current column knocked out from the top down continuous j brick, including this column knocked out of this column in total knocked down the K block, the maximum value of the sum. For the condition of knocking down bricks, all the bricks above the brick were knocked out, and the bricks above the brick were also knocked out, the former in the state has been expressed, the latter can be limited in the transfer.
for calculating the sum of the values of the blocks of J bricks before each column, the prefix and processing can be obtained by O (1).
Equation of State transfer: F[i][j][k]=max (F[i-1][p][k-j]+sum[i][j]), j-1≤p≤i-1, wherein SUM[I][J] represents the sum of the values of the pre-block J blocks of the first row.
Code:
#include <stdio.h>#include <string.h>int N,m,ans=-1;int a[ -][ -],sum[ -][ -],s[ -],f[ -][ -][550];int max (int a,int b) {return a>b?a:b;}//f[I][J][kWhen I hit column I, I knocked out J bricks from the top, totaling the maximum value of K bricks//sum[I][J] denotes the value of the first J block before the knock-out of the line int main () {//freopen ("brike.in", "R", stdin);//freopen ("Brike.out", "w", stdout);scanf ("%d%d", &n,&m);for (int i=1;i<=n;i++) {for (int j=i;j<=n;j++) {scanf ("%d", &a[i][j]);Sum[i][j]=sum[i-1][j]+a[i][j]; } }for (int i=1;i<=n;i++) {S[i]=s[i-1]+i; } for (int i=1;i<=n;i++) {for (int j=0;j<=i;j++) {for (int p=max (j-1,0);p <=i-1;p++) {for (int k=j+s[p];k<=m;k++) {F[i][j][k]=max (F[i][j][k],f[i-1][p][k-j]+sum[j][i]);Ans=max (ans,f[i][j][m]); } } } }printf ("%d\n", ans);return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
NOIP Simulation 21