codeforces算法题和男人人生三禁忌

Educational Codeforces Round 89C. Palindromic Paths

题目链接

https://codeforc.es/contest/1366/problem/C

题意

题意是有个01矩阵,完了要改最小数量的格子,使得左上角到右下角的所有路径是回文路径。

三禁忌

活了这么大,我总结出了世界上三个绝对不能碰的禁忌:

  • 烤了1小时鸡腿的烤箱

  • 地宫东南角的蜡烛灭掉之后,棺材里的冥器。

  • CF的EDU局

  • 头一样东西小时候总是舔,完了舌头暂时报废次数多了,现在渐渐不嘴欠了。

  • 第二样东西是书上说的,我自己也没试过,有兴趣可以趁着月黑风高去试试,但是能不能生存下来就不好说了。

  • 但是后一样,真的忍不住,屡教不改,每次都掉分,但总有上分的侥幸心理。这可能跟赌徒发誓不在碰老千,完了剁手都忍不住一样。。。

这次我又没忍住,果然死的很难看。

题解

一道c题整这么难。仔细想想就会发现满足条件的矩阵满足一些性质:矩阵中心对称(保证回文),各个主对角线上,每条对角线元素必须相同(保证同距离相同),但是回文长度为奇数的话中间一个对角线可以不变。那么就只要看看每条对角线那0多还是1多就完了。少数服从多数。

AC代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int NN=40;
int aa[NN][NN],a[NN][NN];
int main(){
	int t;scanf("%d",&t);
	while(t--){
		int n,m;scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&aa[i][j]);
		if(n>m){
			for(int i=1;i<=m;i++){
				for(int j=1;j<=n;j++)a[i][j]=aa[j][i];
			}
			swap(n,m);
		}
		else{
			for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]=aa[i][j];
		}
		int len=n+m-1;
		int ans=0;
		if(len%2){
			for(int i=1;i<=len/2;i++){
				int up=min(i,n);
				int rec0=0,rec1=0;
				for(int j=1;j<=up;j++){
					if(a[j][i-j+1]==1)rec1++;
					else rec0++;
					if(a[n-j+1][m-i+j]==1)rec1++;
					else rec0++;
				}
				ans+=min(rec0,rec1);
			}
		}
		else{
			for(int i=1;i<=len/2;i++){
				int up=min(i,n);
				int rec0=0,rec1=0;
				for(int j=1;j<=up;j++){
					if(a[j][i-j+1]==1)rec1++;
					else rec0++;
					if(a[n-j+1][m-i+j]==1)rec1++;
					else rec0++;
				}
				ans+=min(rec0,rec1);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

我这个代码写丑了,其实两种情况代码是一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值