1. 程式人生 > 實用技巧 >codeforce Round #665(div 2)A B C

codeforce Round #665(div 2)A B C

A. Distance and Axis

題意:在一個0x軸上,給了a在0x軸上的座標,要你放一個b點使得abs(0B - AB)的值等於 k,但是有的時候如果不移動A點就不能實現這個條件,所以要你求,移動A點的最小距離,讓你滿足這個條件。

分析:這是要求0B和AB的差距,也就是它們之間的相差多少,也就是將0A分成三份,兩份相同的距離就是0B和AB相同的部分x,還有一部分就是0B和AB的相差距離,也就是k,那麼我們就可以表示為2x + k = n,所以我們可以從這個式子中分析出,只要n >= k ,並且n減去一個偶數的結果要等於k這個偶數可以是0,如果沒有這樣的偶數的話,那麼A只需要往後移動一步就可以了,反之一步都可以不用,如果n < k的話,那就可以讓A移動到(0,k),這樣就可以將B點放在原點就可以了。

下面看AC程式碼:

 1 #include <bits/stdc++.h>
 2 #include <iostream>
 3 #include <cstdio>
 4  
 5 using namespace std;
 6 typedef long long ll;
 7 const int ma = 1e5 + 10;
 8 int n,m,k,num[ma];
 9 char c[ma];
10 string s;
11  
12 int main()
13 {
14     int t;
15     scanf("%d",&t);
16     //
2x + k = n 17 while(t--) 18 { 19 scanf("%d%d",&n,&k); 20 if(n < k) 21 cout<<k - n<<endl; 22 else if(n == k) 23 cout<<0<<endl; 24 else 25 { 26 if((n - k) & 1) 27 puts("
1"); 28 else 29 puts("0"); 30 } 31 } 32 return 0; 33 }
A

B. Ternary Sequence

題意:輸入給出六個數字,前三個數字分別為a的0,1,2的個數,也就是說,x1是有x1個0,y1是有y1個1,z1是有z1個2,並且保證a和b的數字數目相等,要你給a,b序列排序,使得sum值最大,a,b的和是這樣求的,如果a[i] > b[i] 那麼在第i個的值就是a[i]*b[i],如果相等的話,第i個值就是0,如果小於的話,第i個值就是-a[i]*b[i].

分析:因為只有a[i] > b[i] 才會產生值,也就是說當a[i] == 1,b[i] == 0,和a[i] == 2,b[i] == 1,這兩種情況,第一種情況產生的值是0,也就是沒意義了,因為它不能給sum做貢獻,第二種產生的值就是2(1*2 = 2)了,所以由分析的結果可以知道,必須要a的2儘可能的和b中的1匹配,這樣就會讓正數最大,因為還有可能會有負數的出現,我們可以分析一下負數出現的可能性,出現負數那就說明a[i] < b[i],當a[i] == 0時,b[i] 可以為1,2。那麼分別的結果為-0*b[i]為0,都為0,當a[i] == 1時,b[i] 可以為2,此時的值為-2,因為相等等於0,所以不做貢獻就可以不考慮了,所以要讓a中的1儘可能的與b中的1,0相匹配,如果還匹配不了,那隻能與b中的2匹配了,然後產生負值。

看程式碼

 1 #include <bits/stdc++.h>
 2 #include <iostream>
 3 #include <cstdio>
 4  
 5 using namespace std;
 6 typedef long long ll;
 7 const int ma = 1e5 + 10;
 8 int n,m,k,num[ma];
 9 char c[ma];
10 string s;
11  
12 int main()
13 {
14     int t;
15     scanf("%d",&t);
16     int x1,y1,z1;
17     int x2,y2,z2;
18     int sum,minn;
19     while(t--)
20     {
21         scanf("%d%d%d",&x1,&y1,&z1);
22         scanf("%d%d%d",&x2,&y2,&z2);
23         sum = 0;
24         minn = min(y2,z1);
25         sum += 2*minn;
26         y2 -= minn,z1 -= minn;
27         if(y1 <= (y2 + x2))
28             cout<<sum<<endl;
29         else
30         {
31             cout<<sum - 2*(y1 - (y2 + x2))<<endl;
32         }
33     }
34     return 0;
35 }
B

C. Mere Array

題意:輸入給出一個長度為n的數字序列,要你給它們排序使得它們遞增,可以進行兩個數的交換,如果滿足條件的話,這個條件就是a[i]和a[j]的最大公約數是這個序列的最小值。如果可以交換成這樣的序列就輸出yes,否則就輸出no。

分析:有題意可知,要交換a[i]和a[j],就得有公共的約數min,那沒必要交換的我們就可以不要動,所以我們可以檢查一下需要交換的所有數是否可以被min整除,如果可以的話,就可以滿足條件了,為什麼呢?因為我們可以用這個最小數和每個需要交換的數字進行交換,這樣就可以保證要交換的兩個數的的最大公約數是min了,否則的話就輸出no。

程式碼:

 1 #include <bits/stdc++.h>
 2 #include <iostream>
 3 #include <cstdio>
 4  
 5 using namespace std;
 6 typedef long long ll;
 7 const int ma = 1e5 + 10;
 8 int n,m,k,num[ma];
 9 int c[ma];
10 string s;
11  
12 int main()
13 {
14     int t;
15     scanf("%d",&t);
16     int x;
17     bool f;
18     while(t--)
19     {
20         scanf("%d",&n);
21         queue<int> q;
22         for(int i = 1; i <= n; i++)
23         {
24             scanf("%d",num+i);
25             c[i] = num[i];
26         }
27         sort(c+1,c+1+n);
28         x = c[1];
29         for(int i = 1; i <= n; i++)
30         {
31             if(num[i] != c[i])
32                 q.push(num[i]);
33         }
34         f = 0;
35         while(!q.empty())
36         {
37             if((q.front() % x))
38             {
39                 f = 1;
40                 break;
41             }
42             q.pop();
43         }
44         if(f)
45             puts("no");
46         else puts("yes");
47     }
48     return 0;
49 }
C