Codeforces Round #557 B. Double Matrix

题面:

传送门

题目描述:

给出两个n*m的矩阵,问:是否能通过交换两个矩阵“对应”位置的元素,使两个矩阵都为“递增”矩阵。

“递增”矩阵定义:每行和每列都要“递增”。

题目分析:

这道题就是个贪心水题,但是我刚开始就是胡思乱想,思路根本不对,再加上放假后的懒惰,就。。。进入正题:

我们可以想出这样一种贪心策略:让前面的值尽可能小,后面才有更大的机会成为“递增”矩阵。我们根据这个贪心策略,可以推出一些东西:

注:下面的a,b是两个题目给出的矩阵

假设我要让a(i, j)尽可能小,也就是:如果a(i, j) > b(i, j),那么就交换a(i, j)和b(i, j),否则不交换。

接下来我们看a(i+1, j)怎么处理?由贪心策略可知,a(i+1, j)和a(i, j)的处理方式一样。

所以,第一步,我们先使矩阵a的所有元素,小于等于矩阵b的所有元素。这时有:a(i, j) <= b(i, j)   (1 <= i <= n, 1 <= j <= m)

第二步,我们直接“贪心地选择”:检查a矩阵是否递增,如果不递增,就交换。如果交换后还不是严格递增就是“impossible”。

为什么?由于我们按照前面的贪心策略设置后,前面的值已经是在合法的情况下是最小的了,如果通过这次交换都不能符合严格递增,就是“impossible”。

检查完a矩阵后,直接看b矩阵是否合法。如果b矩阵不是每行每列严格递增,就是“impossible”,为什么?

当b矩阵有某行(列)的某个元素不是严格递增时,肯定要通过“交换”来符合某行(列)递增,但问题是:

假如b(i, j)在检查a矩阵时没交换过,也就是a(i, j) <= b(i, j)。大的(b(i, j))都不能满足递增,交换后小的(a(i, j))更不能满足递增了。

假如b(i, j)在检查a矩阵时交换过,也就是说,因为a矩阵不符合题意才交换的,这时如果再交换一次,虽然b矩阵可能符合题意,但是a矩阵又不符合题意了。

综上,只要b矩阵不合法,就输出"impossible"。

AC代码(ps:之前我想边交换边检查a矩阵,但是老是wa,所以最终写了个交换完后再检查的代码):

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 int n, m;
 5 int a[55][55], b[55][55];
 6  
 7 bool check(int a[][55], int mode){  //mode == 1: 对矩阵a进行操作, mode == 2: 检查是否合法
 8     for(int i = 0; i < n; i++){
 9         for(int j = 0; j < m; j++){
10             if(i > 0 && a[i-1][j] >= a[i][j]){
11                 if(mode) swap(a[i][j], b[i][j]);
12                 else return false;
13             }
14             if(j > 0 && a[i][j-1] >= a[i][j]){
15                 if(mode) swap(a[i][j], b[i][j]);
16                 else return false;
17             }
18         }
19     }
20     return true;
21 }
22  
23 void init(int a[][55]){
24     for(int i = 0; i < n; i++){
25         for(int j = 0; j < m; j++){
26             scanf("%d", &a[i][j]);
27         }
28     }
29 }
30  
31 int main(){
32     scanf("%d%d", &n, &m);
33     init(a); init(b);
34  
35     for(int i = 0; i < n; i++){
36         for(int j = 0; j < m; j++){
37             if(a[i][j] > b[i][j]){
38                 swap(a[i][j], b[i][j]);  //第一步
39             }
40         }
41     }
42  
43     //第二步
44     check(a, 1);   //需要交换就交换
45  
46     if(!check(a, 0) || !check(b, 0)){   //检查矩阵a和矩阵b是否合法
47         printf("Impossible\n");
48         return 0;
49     }
50     printf("Possible\n");
51     return 0;
52 }

原文地址:https://www.cnblogs.com/happy-MEdge/p/11159309.html

时间: 2024-11-02 02:13:02

Codeforces Round #557 B. Double Matrix的相关文章

二分查找/暴力 Codeforces Round #166 (Div. 2) B. Prime Matrix

题目传送门 1 /* 2 二分查找/暴力:先埃氏筛选预处理,然后暴力对于每一行每一列的不是素数的二分查找最近的素数,更新最小值 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 using namespace std; 8 9 const int MAXN = 5e2 + 10; 10 const int MAXM = 1e6 + 10; 11 const int INF = 0

Educational Codeforces Round 40 C. Matrix Walk( 思维)

Educational Codeforces Round 40 (Rated for Div. 2) C. Matrix Walk time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output There is a matrix A of size x?×?y filled with integers. For every , *A**i,?

Codeforces Round #277.5 (Div. 2) JAVA版题解

Codeforces Round #277.5 (Div. 2) A. SwapSort time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output In this problem your goal is to sort an array consisting of n integers in at most n swaps. For t

Codeforces Round #259 (Div. 2) 题解

A. Little Pony and Crystal Mine time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Twilight Sparkle once got a crystal from the Crystal Mine. A crystal of size n (n is odd; n?>?1) is an n?×?n 

Codeforces Round #593 (Div. 2)

Codeforces Round #593 (Div. 2) A. Stones 思路:水题 先取第一堆中的每一个和先取第二堆中的每一个进行比较就行了 AC代码 #include <algorithm> #include <iomanip> #include <iostream> #include <map> #include <math.h> #include <queue> #include <set> #includ

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #315 (Div. 1)

A. Primes or Palindromes? time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Rikhail Mubinchik believes that the current definition of prime numbers is obsolete as they are too complex and un

Codeforces Round #272 (Div. 2) B. Dreamoon and WiFi (超几何分布)

题目链接:Codeforces Round #273 (Div. 2) B. Dreamoon and WiFi 题意:"+"表示前进1个单位,"-"表示后退1个单位,问以0为起点经过S1,S2两个命令后达到的位置相同的概率. 思路:统计"+"和"-"的数量.如果S2中的"+"或者"-"比S1中的多,概率是0.其他条件下,形成的是超几何分布. AC代码: #include <std