Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B(模拟) && codeforce 724B Batch Sort

54 篇文章 0 订阅



B. Batch Sort
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a table consisting of n rows and m columns.

Numbers in each row form a permutation of integers from 1 to m.

You are allowed to pick two elements in one row and swap them, but no more than once for each row. Also, no more than once you are allowed to pick two columns and swap them. Thus, you are allowed to perform from 0 to n + 1 actions in total. Operations can be performed in any order.

You have to check whether it's possible to obtain the identity permutation 1, 2, ..., m in each row. In other words, check if one can perform some of the operation following the given rules and make each row sorted in increasing order.

Input

The first line of the input contains two integers n and m (1 ≤ n, m ≤ 20) — the number of rows and the number of columns in the given table.

Each of next n lines contains m integers — elements of the table. It's guaranteed that numbers in each line form a permutation of integers from 1 to m.

Output

If there is a way to obtain the identity permutation in each row by following the given rules, print "YES" (without quotes) in the only line of the output. Otherwise, print "NO" (without quotes).

Examples
input
2 4
1 3 2 4
1 3 4 2
output
YES
input
4 4
1 2 3 4
2 3 4 1
3 4 1 2
4 1 2 3
output
NO
input
3 6
2 1 3 4 5 6
1 2 4 3 5 6
1 2 3 4 6 5
output
YES
Note

In the first sample, one can act in the following way:

  1. Swap second and third columns. Now the table is
    1 2 3 4
    1 4 3 2
  2. In the second row, swap the second and the fourth elements. Now the table is
    1 2 3 4
    1 2 3 4

题意:给你一个矩阵n行m列,每一行由1-m这m个数字组成,每行都可以交换两个数字,每一行最多交换一次,你还有一次交换任意两列的机会,但是这个一共只有一次,也就是说你最多有n+1次操作,n次操作行,1次交换列,问你能不能让每一行都是上升的,也就是1到m连续上升。

思路:一开始我觉得是个思维题,一直在找某个点可以区分yes跟no,找了一会没找到。。。发现n跟m只有区区的20,那就直接暴力啊。。其实是个小模拟,只要所有的行里面只有两个或者没有跟上升序列(正确的序列)不一样的这个矩阵就可以,我们只有一次交换任意两列的机会,那如果可以的话,说明交换某两列之后,所有的行都只有两个或者没有需要交换的元素,那就模拟所有交换两列的情况,判断每种情况是不是可以达到要求。注意:每交换的时候要先判断一次,因为他可能一开始就达到了要求,你交换了反而达不到要求。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 25;
int a[maxn][maxn], n, m;
int check()  //要学会写单独函数
{
    for(int i = 1; i <= n; i++)
    {
        int ans = 0;
        for(int j = 1; j <= m; j++)
            if(a[i][j] != j) ans++;
        if(ans > 2) return 0;
    }
    return 1;
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
        {
            scanf("%d", &a[i][j]);
        }
    if(check()) {printf("YES\n");return 0;}
    for(int i = 1; i <= m; i++)
    {
        for(int j = i+1; j <= m; j++)
        {
            for(int k = 1; k <= n; k++)
                swap(a[k][i], a[k][j]);
            if(check()) {printf("YES\n");return 0;}
            for(int k = 1; k <= n; k++)  //注意交换完了要复原,否则矩阵就一直是乱的了
                swap(a[k][i], a[k][j]);
        }
    }
    printf("NO\n");
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值