题目链接:http://agc016.contest.atcoder.jp/tasks/agc016_c
题解:挺简单的构造,很容易想到的构造方法就是(h*w)的小矩阵里其他值赋值为1,最后一个赋值为(h*w)。这只是最基础的构造,然后
判断count - (H * W - count) * (h * w - 1)(count表示基础构造后正数的个数)是否大于0,如果大于0都可以构造,怎么构造就是将正的不断+1,负的不断-(h*w-1)
就行。如果小于等于0就要看初始的sum值(sum表示基础构造后全部数的和)如果sum大于0就行,否则不能构造。
#include <iostream> #include <cstring> using namespace std; const int M = 5e2 + 10; int mmp[M][M] , ans[M][M]; int main() { int H , W , h , w; cin >> H >> W >> h >> w; for(int i = 1 ; i <= H ; i++) { for(int j = 1 ; j <= W ; j++) { ans[i][j] = 1; } } for(int i = 1 ; i <= H ; i++) { if(i % h == 0) { for(int j = 1 ; j <= W ; j++) { if(j % w == 0) { ans[i][j] = -(h * w); } } } } int count = 0 , cnt = 0; for(int i = 1 ; i <= H ; i++) { for(int j = 1 ; j <= W ; j++) { if(ans[i][j] > 0) count++; cnt += ans[i][j]; } } if(count - (H * W - count) * (h * w - 1) <= 0 && cnt <= 0) cout << "No" << endl; else { cout << "Yes" << endl; int sum = 0; for(int i = 1 ; i <= H ; i++) { for(int j = 1 ; j <= W ; j++) { sum += ans[i][j]; } } int num1 = count , num2 = H * W - count; int dif = num1 - num2 * (h * w - 1); if(sum <= 0) { int gg = -sum; int ad = gg / dif + 1; for(int i = 1 ; i <= H ; i++) { for(int j = 1 ; j <= W ; j++) { if(ans[i][j] > 0) ans[i][j] += ad; else ans[i][j] -= ad * (h * w - 1); } } } for(int i = 1 ; i <= H ; i++) { for(int j = 1 ; j <= W ; j++) { cout << ans[i][j] << ' '; } cout << endl; } } return 0; }