1. 程式人生 > >AGC 016 C - +/- Rectangle

AGC 016 C - +/- Rectangle

特殊 puts 開始 一個 bsp its using http ask

題面在這裏!

結合了貪心的構造真是妙啊2333

一開始推式子發現 權是被多少個w*h矩形覆蓋到的時候 帶權和 <0 ,權都是1的時候帶權和 >0,也就是說被矩形覆蓋的多的我們要讓它盡量小。

但這個好像並沒有什麽亂用的樣子QWQ,不過這卻引導出了我的第一個想法:能否選出盡量少的特殊點使得他們等於 -w*h,而其他不是特殊點的位置等於1,並且每個w*h的矩陣都包含至少一個特殊點。

再想一想發現讓 i%w==0 且 j%h==0 的點 (i,j) 作為特殊點是最優的了(可能有相同效果的方案但是沒有更優的了).

於是先這麽填然後看最後的總和是否>0輸出答案。。。

果斷的交了一發,於是WA了 QWQ

那麽問題出在哪裏呢?

主要是沒有動手算。

於是便有了代碼註釋上的正解QWQ (這裏補充一下代碼註釋裏的原理,如果y=1的話那麽後面那個-1占的權重太大了很可能會使結果<=0,讓y變大就相當於讓-1的絕對值減小,使得 y - 1/w/h 與 y 的相對差盡量小,小到可以忽略的時候就是正解啦)

// n/w * m/h 個特殊點
// 設特殊點權值為x,其他點為y,那麽滿足:
// x + y *(w*h-1) < 0   =>  x = y * (1 - w*h) - 1
// n/w * m/h * (x-y) + y * n * m > 0 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=505;

int a[N][N],n,m,w,h,v;
ll sum=0;

int main(){
	scanf("%d%d%d%d",&n,&m,&w,&h),v=1000*(1-w*h)-1;
	for(int i=w;i<=n;i+=w)
		for(int j=h;j<=m;j+=h) a[i][j]=v;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		    if(a[i][j]) sum+=(ll)a[i][j];
	        else sum+=(ll)1000,a[i][j]+=1000;

	if(sum<=0){ puts("No"); return 0;}

	puts("Yes");
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++) printf("%d ",a[i][j]);
		puts("");
	}
	
	return 0;
}

AGC 016 C - +/- Rectangle