zoj 3497 Mistwald

    技术2022-05-19  24

    //11年浙江省赛K题,,比赛时候没出,当时老想的是判环然后组合

    //watashi是这么说滴:"赛前,裁判们普遍认为这题属于中档题,或者说是银牌题。结果是,现场所有能过这道题的队伍都凭借7+AC拿到了金牌。很多队伍前期都用没什么前途的方法尝试C和E,直到过K的队伍多起来才注意到这道中档题。我觉得认清哪题该搞,哪题该先放着,是很重要的一种能力。当然,大多数队伍还是习惯跟风,而这次省赛,实力很强的队伍太少,造成了比赛中期无风可跟的悲剧。".

    //就题目而言涉及到  Strassen矩阵乘法 + 快速计算乘方的算法 + 矩阵的次幂 和 计算图顶点之间的通路数 和 连通性

    //细节方面涉及到不能用[M][N]点更新邻接矩阵的次幂,,但是如果是一次幂的话 我们又要使用到 [M][N] 点与单位矩阵相乘的结果,这就是代码中base的意义

    //至于优化到(n^2),,,表示很无力

    #include <iostream> #include <string> #include <map> #include <vector> #include <memory.h> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int INF=1<<30; bool A[30][30],temp[30][30]; int m,n,l; inline void initTemp(){ for(int i=0;i<=l;i++) for(int j=0;j<=l;j++) if(i==j) temp[i][j]=1; else temp[i][j]=0; } inline void mul(bool a[30][30],bool b[30][30],int base=0){ bool c[30][30]; memset(c,0,sizeof(c)); for(int i=1;i<=l;i++){ for(int j=1;j<=l;j++){ for(int k=1;k<l+base;k++){ c[i][j]|=a[i][k]&b[k][j]; } } } memcpy(a,c,sizeof(c)); } void pow(int p){ int num=0; initTemp(); if(!p){ memcpy(A,temp,sizeof(temp)); return ; } while(p>1){ if(p&1){ if(num++) mul(temp,A); else mul(temp,A,1); } mul(A,A); p>>=1; } if(num++) mul(A,temp); else mul(A,temp,1); } int main() { freopen("i.txt","r",stdin); bool t[30][30],find; char c; int nCase, x1,y1,x2,y2,x3,y3,x4,y4, Q,p; scanf("%d",&nCase); while(nCase--){ memset(A,0,sizeof(A)); scanf("%d %d",&m,&n); scanf("%c",&c); l=m*n; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ scanf("((%d,%d),(%d,%d),(%d,%d),(%d,%d))", &x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4); scanf("%c",&c); A[(i-1)*n+j][(x1-1)*n+y1]=1; A[(i-1)*n+j][(x2-1)*n+y2]=1; A[(i-1)*n+j][(x3-1)*n+y3]=1; A[(i-1)*n+j][(x4-1)*n+y4]=1; } } memcpy(t,A,sizeof(t)); cin>>Q; while(Q--){ cin>>p; memcpy(A,t,sizeof(t)); pow(p); if(!A[1][l]) cout<<"False"<<endl; else{ find=1; for(int i=1;i<l;i++){ if(A[1][i]){ cout<<"Maybe"<<endl; find=0; break; } } if(find) cout<<"True"<<endl; } } cout<<endl; } return 0; }


    最新回复(0)