题意:
给你一个奇怪的打印机,它有如下两个特殊的打印规则:
每一次操作时,打印机会用同一种颜色打印一个矩形的形状,每次打印会覆盖矩形对应格子里原本的颜色。
一旦矩形根据上面的规则使用了一种颜色,那么 相同的颜色不能再被使用 。
给你一个初始没有颜色的 m x n 的矩形 targetGrid ,
其中 targetGrid[row][col] 是位置 (row, col) 的颜色。
如果你能按照上述规则打印出矩形 targetGrid ,请你返回 true ,否则返回 false 。
数据范围:
m == targetGrid.length
n == targetGrid[i].length
1 <= m, n <= 60
1 <= targetGrid[row][col] <= 60
解法:
首先求出每个颜色对应的矩形范围.
每个颜色k对其矩形内部的其他颜色x建边,表示x是再k之后涂色的.
建出来的图只要没有环则合法,
判断环用拓扑排序即可.
code:
const int maxm=66;
int xmi[maxm],xma[maxm];
int ymi[maxm],yma[maxm];
int g[maxm][maxm];
int d[maxm];
class Solution {
public:
void init(){
memset(g,0,sizeof g);
memset(d,0,sizeof d);
for(int i=0;i<maxm;i++){
xmi[i]=ymi[i]=1e9;
xma[i]=yma[i]=-1e9;
}
}
bool isPrintable(vector<vector<int>>& a) {
init();
int n=a.size(),m=a[0].size();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int t=a[i][j];
xmi[t]=min(xmi[t],i);
xma[t]=max(xma[t],i);
ymi[t]=min(ymi[t],j);
yma[t]=max(yma[t],j);
}
}
for(int k=1;k<=60;k++){
if(xmi[k]==1e9)continue;
for(int i=xmi[k];i<=xma[k];i++){
for(int j=ymi[k];j<=yma[k];j++){
if(a[i][j]!=k){
if(!g[k][a[i][j]]){
g[k][a[i][j]]=1;
d[a[i][j]]++;
}
}
}
}
}
queue<int>q;
for(int i=1;i<=60;i++){
if(!d[i]){
q.push(i);
}
}
while(q.size()){
int x=q.front();q.pop();
for(int i=1;i<=60;i++){
if(g[x][i]){
if(d[i]){
d[i]--;
if(!d[i]){
q.push(i);
}
}
}
}
}
for(int i=1;i<=60;i++){
if(d[i])return 0;
}
return 1;
}
};