CF768div2A-C

一、题目分析

  A.Min Max Swap

    题意:给你两个数组,你可以操作任意次,a【i】和b【i】交换,要求你求出a数组最大值和b数组最大值相乘的最小值。

    你把较大的放入a数组,然后把较小的放入b数组,这样两个数组的最大值相乘一定是最小值。

    

    代码实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 inline ll read()
 5 {
 6     ll s = 0,w = 1;
 7     char ch = getchar();
 8     while(ch < '0' || ch > '9'){
 9         if(ch == '-') w = -1;
10             ch = getchar();
11     }
12     while(ch >= '0' && ch <= '9'){
13         s = (s << 1) + (s << 3) + (ch ^ 48);
14         ch = getchar();
15     }
16     return s * w;
17 }
18 inline void write(ll x)
19 {
20     if(x < 0) putchar('-'),x = -x;
21     if(x > 9) write(x / 10);
22     putchar(x % 10 + '0');
23 }
24 int a[10010],b[10010];
25 int main()
26 {
27     int t,n;
28     cin >> t;
29     while(t--){
30         int l;
31         cin >> n;
32         for(int i = 1;i <= n;i++)
33             a[i] = read();
34         for(int i = 1;i <= n;i++)
35             b[i] = read();
36         for(int i = 1;i <= n;i++)
37             if(b[i] < a[i])
38                 swap(a[i],b[i]);
39         int amax = -1,bmax = -1;
40         for(int i = 1;i <= n;i++){
41             amax = max(amax,a[i]);
42             bmax = max(bmax,b[i]);
43         }
44         cout << amax * bmax << endl;
45     }
46 }

 

  B.Fun with Even Subarrays

    题意:给定你一个序列,每次你可以选择一个l和k(l,k>=1),把a【l】= a【l + k】 a【l + 1】 = a【l + k + 1】....,问这样最少操作多少次可以使这个序列的值全部相等

    分析:可以知道我们如果要保证整个序列都相等的话,我们只能从序列的最后往前面复制,但是值得注意的是我们在复制的过程中,已经等于我们最后一个数字的我们可以利用起来,这样就可以最小化                              操作次数。

    代码实现

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 inline ll read()
 5 {
 6     ll s = 0,w = 1;
 7     char ch = getchar();
 8     while(ch < '0' || ch > '9'){
 9         if(ch == '-') w = -1;
10             ch = getchar();
11     }
12     while(ch >= '0' && ch <= '9'){
13         s = (s << 1) + (s << 3) + (ch ^ 48);
14         ch = getchar();
15     }
16     return s * w;
17 }
18 inline void write(ll x)
19 {
20     if(x < 0) putchar('-'),x = -x;
21     if(x > 9) write(x / 10);
22     putchar(x % 10 + '0');
23 }
24 int a[200010];
25 int main()
26 {
27     int t,n;
28     cin >> t;
29     while(t--){
30         cin >> n;
31         int ans = 0;
32         for(int i = 1;i <= n;i++)
33             a[i] = read();
34         for(int i = n;i >= 1;){
35             if(a[i] == a[n])
36                 i--;
37             else {
38                 i -= n - i;
39                 ans++;
40             }
41         }
42         cout << ans << endl;
43     }
44 }

 

  C. And Matching

    题意:给定一个数n和k(n为2的幂次方,k为0-n-1),问你从0-n-1,中能否有n/2对&(按位与)和为k,如果有,则输出相应的构造方案,没有则输出-1 

    分析:

      第一种情况k = 0,一个数按位与上他的异或数一定为0,比如说2 二进制位010  异或数为101,这样与起来肯定为0

      第二种情况k != n-1,我们可以让k与n-1与起来结果肯定还是k,但是我们剩下的要做到和为0,怎么做呢,因为我们拿掉了k,和n-1,那么k的异或没有拿掉,而且n-1的异或也没拿掉,所以让n-1的与k的异或再与一定为0,因为n-1的异或一定是0,所以与任何数与一定是0

      第三种情况k == n-1,此时我们可以让n-2与n-1与上,则会出现n-2,那还差1,怎么凑出来呢,我们知道n为偶数,既然n-2被用掉了,那么我们拿n-3试试,n-3肯定是奇数,二进制最后一位肯定是1,那么我们再拿出1来与他相与,则一定为1,那么我们还有0,(n-3)的异或值没用掉,所以让他们相与肯定会得0,其他的全部按照第一种方案构造得0,即可得到和为n-1的n/2的数对。

    代码实现   

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 inline ll read()
 5 {
 6     ll s = 0,w = 1;
 7     char ch = getchar();
 8     while(ch < '0' || ch > '9'){
 9         if(ch == '-') w = -1;
10             ch = getchar();
11     }
12     while(ch >= '0' && ch <= '9'){
13         s = (s << 1) + (s << 3) + (ch ^ 48);
14         ch = getchar();
15     }
16     return s * w;
17 }
18 inline void write(ll x)
19 {
20     if(x < 0) putchar('-'),x = -x;
21     if(x > 9) write(x / 10);
22     putchar(x % 10 + '0');
23 }
24 int main()
25 {
26     int t;
27     cin >> t;
28     while(t--){
29         int n,k;
30         n = read();
31         k = read();
32         if(n == 4 && k == 3)
33             cout << -1 << endl;
34         else if(k == 0){
35             for(int i = 0;i < n / 2;i++)
36                 cout << i << ' ' << (i ^ (n - 1)) << endl;
37         }
38         else if(k >= 0 && k < n - 1){
39             cout << 0 << ' ' << ((n - 1) ^ k) << endl;
40             cout << k << ' ' << n - 1 << endl;
41             for(int i = 1;i < n / 2;i++){
42                 if(i != ((n - 1) ^ k) && i != k)
43                     cout << i << ' ' << ((n - 1) ^ i)<< endl;
44             }
45         }
46         else{
47             cout << 0 << ' ' << 2 << endl;
48             cout << 1  << ' ' << n - 3 << endl;
49             cout << n - 2 << ' ' << n - 1 << endl;
50             for(int i = 3;i < n / 2;i++)
51                 cout << i << ' ' <<  ((n - 1) ^ i) << endl;
52         }
53     }
54 }
posted @ 2022-01-28 19:33  scannerkk  阅读(49)  评论(0)    收藏  举报