1. 程式人生 > >EOJ Monthly 2018.10

EOJ Monthly 2018.10

#3642 oxx 的小姐姐們

oxx 和他的小姐姐(們)躺在圖書館前的大草坪上看星星。

有強迫症的 oxx 想要使得他的小姐姐們正好躺成一塊 n×m 的長方形。

已知小姐姐的形狀是 1×p 的長方形(可以橫著或豎著躺)。小姐姐從 1 到 nm 編號總共有 nm 個(如果可以的話,絕對夠用)。

P.S. 小姐姐是 1×p 的是因為她們比較苗條。

輸入

輸入三個整數 nmp (1n,m,p100

p 是質數)。

輸出

如果不行,輸出 No

否則輸出 Yes。隨後輸出 n 行 m 列正整數用空格隔開。同一個小姐姐用相同的數字表示,不同的小姐姐用不同的數字表示。數字應是在 [1nm] 範圍內的正整數。同一個數字至多出現 p 次,這 p 次應該在橫向連續,或者縱向連續。

如果有多解輸出任意一解。

樣例

input
2 3 2
output
Yes
2 2 3
1 1 3
input
3 3 2
output
No
input
3 3 3
output
Yes
2 2 2
1 1 1
3 3 3
input
2 3 2
output
Yes
6 3 3
6 4 4
input
4 2 2
output
Yes
2 7
2 7
5 5
3 3

提示

請注意對於最後一組樣例輸出:

2 1
2 1
1 2
1 2

是不合法的。因為不同的小姐姐必須用不同的數字表示。你居然把 1 號小姐姐和 2 號小姐姐克隆了 QAQ。

解題思路:p是質數,如果n*m%p!=0時,顯然為"No";否則一定能用多塊1*p的矩形覆蓋滿方陣:考慮先對行進行橫線填充,再對行剩下的列進行縱向填充。

AC程式碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn=105;
 5 int n,m,p,t,cnt,tp,mp[maxn][maxn];
 6 int main(){
 7     while(cin>>n>>m>>p){
 8         t=n*m;
 9         if(t%p)cout<<"No"<<endl;
10         else{
11             memset(mp,0,sizeof(mp));cnt=1;
12             cout<<"Yes"<<endl;
13             for(int x=1;x<=n;++x){///先對行進行填充
14                 for(int y=1;y<=m-m%p;++y){
15                     mp[x][y]=cnt;
16                     if(y%p==0)cnt++;///填滿一塊1*p的矩形
17                 }
18             }
19             for(int y=m-m%p+1;y<=m;++y){///再對剩餘的列進行填充
20                 for(int x=1;x<=n-n%p;++x){
21                     mp[x][y]=cnt;
22                     if(x%p==0)cnt++;
23                 }
24             }
25             for(int i=1;i<=n;++i)
26                 for(int j=1;j<=m;++j)
27                     cout<<mp[i][j]<<(j==m?'\n':' ');
28         }
29     }
30     return 0;
31 }