题解:
今天最难的题???
根据抽屉原理,必然有至少一个行或者列是根本没有动过的。
枚举这个行和列,则这一行或列上所有点的颜色来源就是另一个方向。
以此类推,我们可以确定所有行列的染色情况,注意到染色被覆盖是一个先后关系,判断合法可以直接拓扑排序,然后就没了。。。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int N=107;
int n,m,tot;
int col[N][N],d[N];
std::vector<int> G[N];
inline void adde(int u,int v){
G[u].push_back(v);++d[v];
}
int c[N],ban[N],q[N],qn;
int ans_siz,ans_id[N],ans_c[N];
inline bool top_sort(){
qn=0;for(int re i=1;i<=tot;++i)if(!d[i])q[++qn]=i;
for(int re i=1;i<=qn;++i)
{int u=q[i];for(int re v:G[u])if(!--d[v])q[++qn]=v;}
return qn==tot;
}
inline void update(int id){
if(!top_sort())return ;int siz=0;
for(int re i=1;i<=tot;++i)if(c[i]&&c[i]!=-1)++siz;
if(siz>=ans_siz)return ;int tp=0;cerr<<"update : "<<id<<"\n";
for(int re i=1;i<=qn;++i)if(c[q[i]]&&c[q[i]]!=-1)ans_id[++tp]=q[i],ans_c[tp]=c[q[i]];
assert(tp==siz);ans_siz=tp;
}
inline void init(){
for(int re i=1;i<=tot;++i)G[i].clear(),c[i]=-1,d[i]=0;
}
inline void check_row(int x){init();
for(int re j=n+1;j<=tot;++j)c[j]=col[x][j];
for(int re i=1;i<=n;++i)if(i!=x){
for(int re j=n+1;j<=tot;++j)
if(c[j]!=col[i][j]){
if(!col[i][j]||(col[i][j]!=c[i]&&c[i]!=-1))return ;
c[i]=col[i][j];adde(j,i);
}
for(int re j=n+1;j<=tot;++j)
if(c[i]!=c[j]&&c[j]==col[i][j])adde(i,j);
}
for(int re i=1;i<=tot;++i)if(ban[i]&&c[i]!=-1&&c[i]!=0)return ;
update(x);
}
inline void check_col(int y){init();
for(int re i=1;i<=n;++i)c[i]=col[i][y];
for(int re j=n+1;j<=tot;++j)if(j!=y){
for(int re i=1;i<=n;++i)
if(c[i]!=col[i][j]){
if(!col[i][j]||(col[i][j]!=c[j]&&c[j]!=-1))return ;
c[j]=col[i][j],adde(i,j);
}
for(int re i=1;i<=n;++i)
if(c[j]!=c[i]&&c[i]==col[i][j])adde(j,i);
}
for(int re i=1;i<=tot;++i)if(ban[i]&&c[i]!=-1&&c[i]!=0)return ;
update(y);
}
signed main(){
#ifdef zxyoi
freopen("iridescent.in","r",stdin);
// freopen("iridescent.out","w",stdout);
#endif
int c;
scanf("%d%d%d",&n,&m,&c);ans_siz=1e9;tot=n+m;
for(int re i=1;i<=n;++i)
for(int re j=n+1;j<=tot;++j)scanf("%d",col[i]+j);
for(int re i=1;i<=n;++i)
for(int re j=n+1;j<=tot;++j)ban[i]|=!col[i][j],ban[j]|=!col[i][j];
for(int re i=1;i<=n;++i)check_row(i);
for(int re j=n+1;j<=tot;++j)check_col(j);
if(ans_siz>n+m)puts("-1"),exit(0);
cout<<ans_siz<<"\n";
for(int re i=1;i<=ans_siz;++i){
if(ans_id[i]>n)cout<<"C ",ans_id[i]-=n;
else cout<<"R ";
cout<<ans_id[i]<<" "<<ans_c[i]<<"\n";
}
return 0;
}