http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=2459
明天省赛,所以今天做几道所谓水题,可惜这个题因为输出写错WA了很久,,,
如果直接枚举矩阵所有的位置是否改变,那么时间复杂度是承受不住的
这道题让我学到的,就是:
1、遇到题先手算模拟,然后尝试找规律吧。这道题的规律就是:第一行一旦确定,那么整个矩阵就可以确定,所以枚举第一行,还可以的
2、if else 一定把所有的情况逻辑都理清,这题Debug的时候稍微变了下写法,又WA了很久,代码也贴在后面了。Debug的时候,重用代码的时候好好理理思路,很可能是老思路跟新思路的差异产生新的bug
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 20;
//const int INF = 0x3fffffff;999
const int INF = 1000000000;
int n,a[MAXN][MAXN],b[MAXN][MAXN];
int Judge(int m)
{
//memset(b,0,sizeof(b));
int tmp=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
b[i][j]=a[i][j];
for(int i=0;i<n;i++) /**/
{
if((m & (1<<i)))
{
if(0 == b[0][i])
{
b[0][i]=1; /*有1表示do*/
tmp++;
}
else
return INF;
}
}
for(int i=1;i<n;i++)
for(int j=0;j<n;j++)
{
int sum=b[i][j];
if(j-1>=0)sum+=b[i-1][j-1];
if(j+1<n)sum+=b[i-1][j+1];
if(i-2>=0)sum+=b[i-2][j];
if(sum%2)
{
if(!b[i][j])
{
b[i][j]=1;
tmp++;
}
else
return INF;
}
} // 这种写法是有问题的,因为
/*以上的步骤都没有检测最后一行,一下测试最后一行*/
for(int i=0;i<n;i++)
{
int sum=0;
if(n-2>=0)sum+=b[n-2][i];
if(i>0)sum+=b[n-1][i-1];
if(i+1<n)sum+=b[n-1][i+1];
if(sum%2)return INF;
}
return tmp;
}
int main()
{
int ncase;
scanf("%d",&ncase);
//while(n--)
for(int icase=1;icase<=ncase;icase++)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&a[i][j]);
int ans = INF;
/*以下是我要借鉴的*/
for(int i=0;i<(1<<n);i++) /*数字位代表状态*/
ans=min(ans,Judge(i));
if(ans == INF)ans=-1;
printf("Case %d: %d\n",icase,ans);
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 20;
//const int INF = 0x3fffffff;999
const int INF = 99999;
int n,a[MAXN][MAXN],b[MAXN][MAXN];
int Judge(int m)
{
//memset(b,0,sizeof(b));
int tmp=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
b[i][j]=a[i][j];
for(int i=0;i<n;i++) /**/
{
if((m & (1<<i)))
{
if(0 == b[0][i])
{
b[0][i]=1; /*有1表示do*/
tmp++;
}
else
return INF;
}
}
for(int i=1;i<n;i++)
for(int j=0;j<n;j++)
{
int sum=0;
if(j-1>=0)sum+=b[i-1][j-1];
if(j+1<n)sum+=b[i-1][j+1];
if(i-2>=0)sum+=b[i-2][j];
if(sum%2)
{
if(!b[i][j])
{
b[i][j]=1;
tmp++;
}
//else 这种情况太二逼了 我居然没发现这个bug
// return INF;
}
else
{
if(b[i][j] == 1)
return INF;
}
} // 这种写法是有问题的,因为
/*以上的步骤都没有检测最后一行,一下测试最后一行*/
for(int i=0;i<n;i++)
{
int sum=0;
if(n-2>=0)sum+=b[n-2][i];
if(i>0)sum+=b[n-1][i-1];
if(i+1<n)sum+=b[n-1][i+1];
if(sum%2)return INF;
}
return tmp;
}
int main()
{
int ncase;
scanf("%d",&ncase);
//while(n--)
for(int icase=1;icase<=ncase;icase++)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&a[i][j]);
int ans = INF;
/*以下是我要借鉴的*/
for(int i=0;i<(1<<n);i++) /*数字位代表状态*/
ans=min(ans,Judge(i));
if(ans == INF)ans=-1;//printf("-1\n");
printf("Case %d: %d\n",icase,ans);
}
return 0;
}