HDOJ 3364 Lanterns 非常恶心的高斯消元

HDOJ 3364 Lanterns 非常恶心的高斯消元

光庭杯的题目,可能是由于自己太菜了,别人认为是很水的题目自己也没做出来。 而且赛后发现这个题很恶心,除了高斯消元以外还考高精度,long long 都过不了,只能用double,不知道出题人怎么想的。。。
#include < iostream >
#include
< cmath >
using   namespace  std;
// 高斯消元 
const   int  maxn = 60 ;
int  n,m;
int  rec[maxn][maxn];
int  cop[maxn][maxn];

inline 
int  fab( int  x) {return x>0?x:-x;}  
inline 
void  swap( int   & x, int   & y) {int tmp=x;x=y;y=tmp;}  

double  gauss()
{
    
int i,j,k,t;
    
for(i=0,j=0;i<n,j<m;i++,j++)
    
{
        
int id=i;
        
for(k=i+1;k<n;k++)if(fab(rec[k][j])>fab(rec[id][j]))id=k;//选绝对值最大的 
        if(id!=i)//找到了绝对值最大所在行,交换行 
        {
            
for(t=j;t<=m;t++)swap(rec[i][t],rec[id][t]);
        }

        
if(rec[i][j]==0){i--;continue;}//说明该j列第i行以下全是0了,则处理当前行的下一列
        for(k=i+1;k<n;k++)   
     
{
            
if(rec[k][j]==0)continue;
            
for(t=j;t<=m;t++)rec[k][t]=rec[k][t]^rec[i][t];
        }

    }

    
for(k=i;k<n;k++)if(rec[k][m]!=0)return 0;//无解
    if(i<=m) return pow(2.0,m-i);
}


int  main()
{
    
int t;
    
int i,j;
    
int q;
    
int casenum=0;
    scanf(
"%d",&t);
    
while(t--)
    
{
        casenum
++;
        memset(rec,
0,sizeof(rec));
        memset(cop,
0,sizeof(cop));
        scanf(
"%d%d",&n,&m);
        
int num;
        
for(i=1;i<=m;i++)
        
{
            scanf(
"%d",&num);
            
for(j=1;j<=num;j++)
            
{

                
int tem;
                scanf(
"%d",&tem);
                rec[tem
-1][i-1]=1;
                cop[tem
-1][i-1]=1;
            }

        }

        scanf(
"%d",&q);
        printf(
"Case %d:\n",casenum);
        
for(i=1;i<=q;i++)
        
{
            
int k;
            
for(j=0;j<n;j++)
                
for(k=0;k<m;k++)
                    rec[j][k]
=cop[j][k];
            
for(j=0;j<n;j++)
            scanf(
"%d",&rec[j][m]);
            
double ans=gauss();
            printf(
"%.0lf\n",ans);
        }



    }

    
return 0;
}

你可能感兴趣的:(HDOJ 3364 Lanterns 非常恶心的高斯消元)