CF1774D Same Count One - two-pointers -

题目链接:https://codeforces.com/contest/1774/problem/D

题解:
比较巧妙,官方题解说的比较详细了,不再赘述了
image

这题的实现也比较巧妙,two-pointers的时候两个指针指向的是行,由题解可知只要是 a>k>b 的话一定能把至少一行变成 k ,这样我们就遇到两行的同一列一个1一个0的时候就直接交换,记录方案就行了

// by SkyRainWind
#include <bits/stdc++.h>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define pii pair<int,int>

using namespace std;

typedef long long ll;
typedef long long LL;

const int inf = 1e9, INF = 0x3f3f3f3f;

int n,m,a[1000005];
struct node{int val,id;}b[1000005];
int ind(int i,int j){return (i-1)*m+j;}
int cmp(node a,node b){return a.val < b.val;}
void solve(){
	int sum = 0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		int le = 0;
		for(int j=1;j<=m;j++){
			scanf("%d",&a[ind(i,j)]);
			if(a[ind(i,j)] == 1)++ le;
		}
		b[i]=node{le,i};
		sum += le;
	}
	if(sum % n)return (void)puts("-1");

	sum /= n;
	int s = sum;
	sort(b+1,b+n+1,cmp);
	int l=1,r=n;
	vector<pair<pii,int>>vc; 
	while(l < r){
		int nl = b[l].id, nr = b[r].id;
		int i=1,j=1;
		while(b[l].val < s && b[r].val > s){
			if(a[ind(nl,i)] == 0 && a[ind(nr,i)] == 1){
				++ b[l].val;
				-- b[r].val;
				vc.push_back(mpr(mpr(nl,nr),i));
				a[ind(nl,i)]=1,a[ind(nr,i)]=0;
			}
			++ i;
		}
		if(b[l].val == s)++ l;
		if(b[r].val == s)-- r;
	}
	printf("%d\n",vc.size());
	for(pair<pii,int>u:vc)printf("%d %d %d\n",u.first.first,u.first.second,u.second);
}

signed main(){
	int te;scanf("%d",&te);
	while(te--)solve();

	return 0;
}
posted @   SkyRainWind  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示