【AtCoder2387】+/- Rectangle

题意

构造一个 H × W H \times W H×W的矩阵,满足一下条件

  • 所有元素为整数,且属于 [ − 1 0 9 , 1 0 9 ] [-10^9,10^9] [109,109]
  • 所有元素和为正数
  • 对每个 h × w h \times w h×w的子矩阵,它的元素和为负数

题解

根据样例,最朴素的想法即为,给满足 x   m o d   h = 0 x\ mod\ h=0 x mod h=0 y   m o d   w = 0 y\ mod\ w=0 y mod w=0的位置 ( x , y ) (x,y) (x,y)标为 − h w -hw hw,其余的全部标为 1 1 1
但是有反例
对于 1 × 4 1\times 4 1×4的矩阵, 1 × 3 1\times 3 1×3的子矩阵,会被标为
1 1 − 3 1 \begin{matrix} 1&1&-3&1 \end{matrix} 1131不合法,可以标为
2 2 − 5 2 \begin{matrix} 2&2&-5&2 \end{matrix} 2252

考虑改进这个方法,将普通的位置标为 k k k x   m o d   h = 0 x\ mod\ h=0 x mod h=0 y   m o d   w = 0 y\ mod\ w=0 y mod w=0的位置 ( x , y ) (x,y) (x,y)标为 − k ( h w − 1 ) − 1 -k(hw-1)-1 k(hw1)1,子矩阵的和即为-1,若能找到k,则就有解。

可以证明当 H   m o d   h = 0 H\ mod\ h=0 H mod h=0 W   m o d   w = 0 W\ mod\ w=0 W mod w=0时,无解,此时可以把 H × W H\times W H×W的矩阵恰好分为整数个 h × w h\times w h×w子矩阵,而每个子矩阵为负数,则整个原矩阵不可能和为正数。

如果不满足以上条件,则原矩阵切成若干子矩阵后,还剩一些边角料,边角料每一格值为 k k k,只要使 k k k足够大,一定能抵消掉前面子矩阵得到的很多-1,所以k越大越好。

实现时直接把k卡到最大即可。

代码

#include<cstdio>
const int MAXN=505;
 
int H,W,h,w;
int arr[MAXN][MAXN];
 
int main()
{
	scanf("%d%d%d%d",&H,&W,&h,&w);
	if(h==1&&w==1)
	{
		puts("No");
		return 0;
	}
	long long sum=0;
	int k=999999999/(h*w-1);
	{
		sum=0;
		for(int i=1;i<=H;i++)
			for(int j=1;j<=W;j++)
			{
				if(i%h==0&&j%w==0)
					arr[i][j]=-k*(h*w-1)-1;
				else
					arr[i][j]=k;
				sum+=arr[i][j];
			}
		if(sum>0)
		{
			puts("Yes");
			for(int i=1;i<=H;i++)
			{
				for(int j=1;j<=W;j++)
					printf("%d ",arr[i][j]);
				puts("");
			}
			return 0;
		}
	}
	puts("No");
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <iostream> #include <string> using namespace std; struct CPoint { int x ; int y ; }; class CRectangle { private: const int id;//常量数据成员 static int total;//静态数据成员 const static string sclass; const static int f=1.0f; CPoint lefttop ; CPoint rightdown ; public: CRectangle( ); CRectangle( CPoint& lt, CPoint& rd ); CPoint GetLefttop() const { return lefttop; } CPoint GetRightdown() const { return rightdown; } void SetLefttop(CPoint & pt) { lefttop=pt; } void SetRightdown(CPoint & pt) { rightdown=pt; } int Getid() const { return id; } static int Gettotal() { return total; } int Area( ) const; int Perimeter( ) const; }; int CRectangle::total=0;//静态数据成员必须在类的外部定义(正好一次)。 const string CRectangle::sclass="CRectangle"; CRectangle::CRectangle( ):id(++total) { lefttop.x=0; lefttop.y=0; rightdown.x=1; rightdown.y=1; } CRectangle::CRectangle( CPoint& lt, CPoint& rd ):id(++total) { lefttop = lt ; rightdown = rd ; } int CRectangle::Area( ) const { int wd= rightdown.x - lefttop.x ; int ht= rightdown.y - lefttop.y ; return wd * ht ; } int CRectangle::Perimeter( ) const { int wd= rightdown.x - lefttop.x ; int ht= rightdown.y - lefttop.y ; return 2 * ( wd + ht ) ; } int main() { CPoint lt, rd; cin >> lt.x >> lt.y; cin >> rd.x >> rd.y; CRectangle crt(lt,rd);//调用有参构造函数 CRectangle crt2;//调用默认构造函数 //创建常量对象 const CRectangle crt3(lt,rd); cout<<"当前创建的矩形个数为:"; cout<<CRectangle::Gettotal()<<endl; //返回矩形的左上和右下点 CPoint lt1=crt.GetLefttop(); CPoint lt2=crt.GetRightdown(); //显示矩形的坐标 cout<<crt.Getid()<<"号矩形的坐标是:"<<"("<<lt1.x<<","<<lt1.y<<"), "; cout<<"("<<lt2.x<<","<<lt2.y<<")"<<endl; //显示矩形的面积和周长 cout << "Area:"<<crt.Area( )<<endl; cout <<"Perimeter:"<<crt.Perimeter( )<<endl; //修改矩形的左上角点 cout<<"请输入矩形新的左上点坐标:"; cin>> lt.x>>lt.y; crt.SetLefttop(lt); lt1=crt.GetLefttop(); //显示修改后矩形的坐标 cout<<"矩形的坐标是:"<<"("<<lt1.x<<","<<lt1.y<<"), "; cout<<"("<<lt2.x<<","<<lt2.y<<")"<<endl; //显示修改后矩形的面积和周长 cout << "Area:"<<crt.Area( )<<endl; cout <<"Perimeter:"<<crt.Perimeter( )<<endl; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值