CF1684C Column Swapping

题目链接

题目大意

在这里插入图片描述

思路

  • 如果全都是升序,不需要变换,直接输出1 1
  • 如果可以通过交换两列实现每一行的数都是升序,就直接交换那两行。在这种情况下,可以只交换一次就得到升序列,那么和排完序不一样的地方肯定有且仅有2处。
  • 如果当前这一行的数和它排完序后的序列,不一样的数超过2处,则一定不可能只交换一次把序列变成升序,那么就输出 -1。

!!!注意不要开二维数组,需要用vector

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, m;
int x, y;
vector<int> g[500005];
bool check(int idx)
{
	//先复制一行
	int a[500005];
	for (int i = 1; i <= m; i ++ )
	{
		a[i] = g[idx][i];
	}
	
	//排序
	sort(a + 1, a + 1 + m);
	int cnt = 0;
	for (int i = 1; i <= m; i ++ )
	{
		//对比不一样的地方有几处
		if (a[i] != g[idx][i])
		{
			cnt ++;
			
			//如果只有两处的话,那么x,y就是要交换的那两个数的下标
			if (cnt == 1) x = i;
			if (cnt == 2) y = i;
		}
		
	}
	return cnt <= 2;
}
 
signed main()
{
	int t;
	cin >> t;
	while (t -- )
	{
		int ff = 0;
		scanf("%lld %lld", &n, &m);
		for (int i = 1; i <= n; i ++ )
		{
			g[i].clear();
			//为了方便从1调用下标,所以放1个极小数去垫一下
			g[i].push_back(-999999);
			
			for (int j = 1; j <= m; j ++ )
			{
				int x;
				scanf("%lld", &x);
				g[i].push_back(x);

				//判断是否不需要改变,直接输出1 1
				if (g[i][j] < g[i][j - 1])  ff = 1;
			}
		}
		//判断是否不需要改变,直接输出1 1
		if (ff == 0)
		{
			printf("1 1\n");
			continue;
		}


		int f = 0;
		for (int i = 1; i <= n; i ++ )
		{
			//把每一行的数据传到函数里面进行判断,传的是第几行
			if (check(i) == 0) //如果超过了两处,说明无法改变,直接输出-1
			{
				f = 1;
				printf("-1\n");
				break;
			}
		}
	
		//如果可以改变
		if (!f) 
		{
			//那就交换只有两处不同的那一行的那个位置,然后交换这两列
			for (int i = 1; i <= n; i ++ )
			{
				swap(g[i][x], g[i][y]);
			}

			//最后再判断换了这两列之后,是否符合要求
			ff = 0;
			for (int i = 1; i <= n; i ++ )
			{
				for (int j = 1; j <= m; j ++ )
				{
					if (g[i][j] < g[i][j - 1])  ff= 1;
				}
			}
			if (!ff) cout << x << " " << y << endl;
			else cout << -1 << endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值