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 //A2x + 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 }
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