HDU 4026

来源:互联网 发布:linux创建用户指定id 编辑:程序博客网 时间:2024/05/22 13:55

这题比赛的时候没写出来,当时理解错题意了,这题意有点不清楚,是一个触屏机的解锁系统,问你有多少种方案。

原来可以任意角度进行滑行,不过不能跳过没按的,简单的来说就是经过所有要按的点,然后要满足这个点是否有一条路线到达这个点,就是这里感觉处理异常困难,分析一下,走过的点可以跳过,那就是按了后还是可以经过的,那么不能经过的点有哪些呢?首先标记为1的点不能经过,为0且没有经过的点,其他点都可以经过。这题的关键不是这里,这样依然会超时,记忆化优话也是tle,关键是gcd,太慢了,可以先预处理了一下,才5*5,一下子就不知道快了多少。

Run IDSubmit TimeJudge StatusPro.IDExe.TimeExe.MemoryCode Len.LanguageAuthor45793772011-09-10 22:40:38Accepted40262156MS8516K1628 BG++xym2010

#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<cmath>#include<algorithm>using namespace std;struct node{int x,y;}nd[16];long long dp[1<<16][16];//状态和当前到达的点int n,m,gp[6][6],pos,gd[6][6],mp[6][6];int gcd(int x,int y){ if (y == 0)        return x;    return gcd(y, x % y);}bool ok(int x,int y,int sta){int x1=nd[x].x,x2=nd[y].x,y1=nd[x].y,y2=nd[y].y;int dx=x2-x1;int dy=y2-y1;int c=gd[abs(dx)][abs(dy)];dx=dx/c;dy=dy/c;for(int i=0;i<=5;i++){x1+=dx;y1+=dy;if(gp[x1][y1]==1)return false;else if(x1==x2&&y1==y2)return true;else if(gp[x1][y1]==0&&(sta&(1<<(mp[x1][y1])))==0)return false;}return false;}long long DP(int st,int k){if(dp[st][k]!=-1)return dp[st][k];if(st==(1<<k)) dp[st][k]=1;else{dp[st][k]=0;for(int j=0;j<pos;j++){if(((1<<j)&st)==0||j==k)continue;if(ok(j,k,st)==0)continue;dp[st][k]+=DP(st-(1<<k),j);}}return dp[st][k];}void work(){long long ans=0;memset(dp,-1,sizeof(dp));for(int i=0;i<pos;i++)      DP((1<<pos)-1,i);for(int i=0;i<pos;i++){ans+=dp[(1<<pos)-1][i];}cout<<ans<<'\n';}void init(){for(int i=0;i<6;i++)for(int j=0;j<6;j++)gd[i][j]=gcd(i,j);}int main(){init();while(scanf("%d%d",&n,&m)!=EOF){pos=0;for(int i=0;i<n;i++)for(int j=0;j<m;j++){scanf("%d",&gp[i][j]);if(gp[i][j]==0){nd[pos].x=i;nd[pos++].y=j;mp[i][j]=pos-1;}}work();}return 0;}


原创粉丝点击