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

 

posted @ 2020-08-24 20:09  好学生就是我  阅读(171)  评论(0编辑  收藏  举报