東京海上日動プログラミングコンテスト2022(AtCoder Beginner Contest 256)C - Filling 3x3 array
問題の要約
6個の整数、h1,h2,h3,w1,w2,w3が与えられる。
縦横3×3のマス目に、以下の条件をすべて満たすように各マスに正の整数を1つずつ書き込むことを考える。
・i=1,2,3について、上からi行目に書き込んだ数の和がhiになる。
・j=1,2,3について、左からj列目に書き込んだ数の和がwjになる。
条件を満たす書き込み方は全部で何通り存在するか?
制約
3<=h1,h2,h3,w1,w2,w3<=30
入力
h1 h2 h3 w1 w2 w3
考え方
1,3×3の行列のマスに名前をつける。
m00 m01 m02
m10 m11 m12
m20 m21 m22
2,3*3で9重のfor文になりそうだが、m02,m12,m20,m21,m22はm00,m01,m10,m11が決まればh1,h2,h3,w1,w2,w3から引き算で求まるので、4重のfor文で大丈夫。
実際のプログラム
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> h(3);
vector<int> w(3);
cin >> h[0] >> h[1] >> h[2];
cin >> w[0] >> w[1] >> w[2];
int ans = 0;
for(int m00 = 1; m00 <= 30; ++m00){
for(int m01 = 1; m01 <= 30; ++m01){
int m02 = h[0] - m00 - m01;
if(m02 <= 0){
continue;
}
for(int m10 = 1; m10 <= 30; ++m10){
int m20 = w[0] - m00 - m10;
if(m20 <= 0){
continue;
}
for(int m11 = 1; m11 <= 30; ++m11){
int m12 = h[1] - m10 - m11;
if(m12 <= 0){
continue;
}
int m21 = w[1] - m01 - m11;
if(m21 <= 0){
continue;
}
int m22_1 = h[2] - m20 - m21;
if(m22_1 <= 0){
continue;
}
int m22_2 = w[2] - m02 - m12;
if(m22_2 <= 0){
continue;
}
if(m22_1 == m22_2){
++ans;
}
}
}
}
}
cout << ans << endl;
return 0;
}