Fill Numbers
Fill Numbers
Time Limit:5000 ms Memory Limit:65536 kB Solved:28Tried: 239
Description
Stephydx invented a new puzzle for you to solve! The puzzle is a matrix with n rows, and each row consists of m grids. Each grid may be empty or have a number in it. But you can assume that there are no more thanTWO empty grids at each row and column. Now, we want to fill numbers in each empty grid to make the sum of each row, and each column equal to some specific numbers.
You have to find out whether the solution is unique, or more than one, or we have no solutions at all.
Input
The first line of the input is an integer T, indicating the test cases. (T<=50)
For each test case, there are two numbers N and M, indicating the size of the matrix (1<=N<=500, 1<=M<=500). Then N lines follow, each
consists of M integers, representing N rows of the matrix. If the grid is empty, that number will be -1, otherwise the number will always be non-negative and no more than 1000.
Then a line with N integers lists the sum we required for each row, from up to bottom. The next line has M integers, listing the sum we required for each column, from left to right.
The absolute value of the required sum of each row and column will not exceed 1000000.
Output
For each test case, first print "Case #k: " first ,in which k represents the case number which starts from 1, then output a word "Unique", "More than one", or "No solution", as described above.
Sample Input
5
2 2
1 1
-1 -1
2 4
3 3
2 2
1 1
-1 -1
2 5
3 3
2 2
1 1
2 2
2 4
3 3
4 4
1 2 3 4
1 -1 -1 2
3 -1 -1 4
5 6 7 8
10 6 14 26
10 13 15 18
2 2
1 -1
2 -1
-1 1
3 -3
Sample Output
Case #1: Unique
Case #2: No solution
Case #3: Unique
Case #4: More than one
Case #5: Unique
Hint
Please note that although the numbers that are already filled in the matrix are all non-negative, a solution with negative numbers is still acceptable. Also if a row or a column has no empty grids, the sum of that row or column will always equal to the required sum we gave.
Source
10th UESTC Programming Contest Final
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int N=1001;
int n,m,a[N][N],r[N],c[N];
int x[N],y[N],degree[N];
vector<int> g[N];
bool f,vis[N];
void judge(int p,int q,int st)
{
int i,j;
for(i=0;i<p;i++)
{
bool f1;int s=0;
for(j=0;j<q;j++)
{
int t=(st?a[i][j]:a[j][i]);
if(t==-1){f1=1;break;}
else s+=t;
}
if(!f1&&s!=(st?r[i]:c[i])) {f=0;return;}
}
}
int calx(int u)
{
int i,s=0;
for(i=0;i<m;i++)if(i!=y[u])s+=a[x[u]][i];
return r[x[u]]-s;
}
int caly(int u)
{
int i,s=0;
for(i=0;i<n;i++)if(i!=x[u])s+=a[i][y[u]];
return c[y[u]]-s;
}
int cal(int u)
{
int i,j,s=0;
for(i=0;i<m;i++) if(i!=y[u]&&a[x[u]][i]==-1)break;
if(i<m)
{
for(j=0;j<n;j++) if(j!=x[u])s+=a[j][y[u]];
return c[y[u]]-s;
}
for(j=0;j<m;j++)if(j!=y[u])s+=a[x[u]][j];
return r[x[u]]-s;
}
int work(int u,int v)
{
int i,s=0;
if(x[u]==x[v])
{
for(i=0;i<m;i++)if(i!=y[u]&&i!=y[v])s+=a[x[u]][i];
return r[x[u]]-s;
}
for(i=0;i<n;i++)if(i!=x[u]&&i!=x[v])s+=a[i][y[u]];
return c[y[u]]-s;
}
int last,last_v;
void dfs(int u,int va)
{
int i,v,sz=g[u].size();vis[u]=1;
last=u,last_v=va;
for(i=0;i<sz;i++)
{
v=g[u][i];
if(!vis[v])
{
int val=work(u,v)-va;
dfs(v,val);
}
}
}
int main()
{
int t,i,j,ca=1;
scanf("%d",&t);
while(t--)
{
f=1;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)for(j=0;j<m;j++)scanf("%d",&a[i][j]);
for(i=0;i<n;i++)scanf("%d",&r[i]);
for(i=0;i<m;i++)scanf("%d",&c[i]);
printf("Case #%d: ",ca++);
judge(n,m,1);if(!f){puts("No solution");continue;}
judge(m,n,0);if(!f){puts("No solution");continue;}
int cnt=0;
for(i=0;i<n;i++)for(j=0;j<m;j++)if(a[i][j]==-1) {x[cnt]=i;y[cnt++]=j;}
for(i=0;i<cnt;i++)g[i].clear();
memset(degree,0,sizeof(degree));
memset(vis,0,sizeof(vis));
for(i=0;i<cnt;i++)for(j=i+1;j<cnt;j++)
{
if(x[i]==x[j]||y[i]==y[j])
{
g[i].push_back(j);
g[j].push_back(i);
degree[i]++;degree[j]++;
}
}
for(i=0;i<cnt;i++)
{
if(!vis[i]&°ree[i]==0)
{
vis[i]=1;
int t1=calx(i),t2=caly(i);
if(t1==t2) a[x[i]][y[i]]=t1;
else {f=0;break;}
}
}
if(!f){puts("No solution");continue;}
for(i=0;i<cnt;i++)
{
if(!vis[i]&°ree[i]==1)
{
int va=cal(i);
dfs(i,va);
if(cal(last)!=last_v){f=0;break;}
}
}
if(!f){puts("No solution");continue;}
bool f1=0;
for(i=0;i<cnt;i++)
{
if(!vis[i]&°ree[i]==2)
{
int s=work(i,g[i][0]);
vis[i]=1;
dfs(g[i][0],s);
if(work(last,i)==last_v)f1=1;
else f=0;
}
}
if(!f)puts("No solution");
else if(f&&f1)puts("More than one");
else puts("Unique");
}
return 0;
}