zoukankan      html  css  js  c++  java
  • hihocoder 北京网赛 boxs #1233 : Boxes

    根据汉诺塔的特点找到保存状态的最简方式。懂得hash的真谛才能ac qaq

    首先从有序状态可以推出所有有解状态。大体是给每个不同的数字以不同的模,根据他们的位置分别哈希,加起来作为该种状态的哈希值。

    这样可以根据这个哈希值取得各个数字的位置,得到当前情况。打表出各种移动的所需要的代价,即可转移到下一个状态

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=20000008;
    int mp7[maxn];
    int mp6[maxn>>1];
    int mp5[maxn>>2];
    int mp4[maxn>>3];
    int mp3[maxn>>4];
    int dp[10][10];
    void bfs(int ha,int mp[],int mod)
    {
    	queue<int>	q;
    	queue<int>	p;
    	q.push(ha);
    	p.push(0);
    	mp[ha]=0;
    	int i,a[10],b[10];
    	int x,y,sx,idx,nx,ny;
    	while(!q.empty())
    	{
    		x=q.front();q.pop();
    		y=p.front();p.pop();
    		 sx=x;idx=0;
    		for(i=1;i<=mod;i++)
    		{
    			a[i]=sx%mod;
    			sx/=mod;
    		}
    		memset(b,INF,sizeof(b));
    		for(i=1;i<=mod;i++)
    			if(b[a[i]+1]>i)
    				b[a[i]+1]=i;
    		b[0]=0;b[mod+1]=0;	
    		for(i=1;i<=mod;i++)
    		{
    			if(b[i]==INF)	continue;
    			if(b[i]<b[i-1])
    			{
    				nx=x-dp[mod][b[i]];
    				if(mp[nx]==-1)
    				{
    					ny=y+1;
    					mp[nx]=ny;
    					q.push(nx);
    					p.push(ny);
    				}
    			}
    			if(b[i]<b[i+1])
    			{
    				nx=x+dp[mod][b[i]];
    				if(mp[nx]==-1)
    				{
    					ny=y+1;
    					mp[nx]=ny;
    					q.push(nx);
    					p.push(ny);
    				}
    			}
    		}
    	}
    }
    void init()
    {
    	int i,j;
    	memset(mp3,-1,sizeof(mp3));
    	memset(mp4,-1,sizeof(mp4));
    	memset(mp5,-1,sizeof(mp5));
    	memset(mp6,-1,sizeof(mp6));
    	memset(mp7,-1,sizeof(mp7));
    	for(i=3;i<=7;i++)
    	{
    		dp[i][1]=1;
    		for(j=2;j<=i;j++)
    			dp[i][j]=dp[i][j-1]*i;
    	}
    	int ans=1;
    	int mod;
    	int md[10];
    	md[1]=1;
    	for(i=3;i<=7;i++)
    	{
    		mod=i;
    		ans=0;
    		for(j=2;j<=i;j++)
    			md[j]=md[j-1]*mod;
    		for(j=i;j>=1;j--)
    			ans=ans+(j-1)*md[i-j+1];
    		if(i==3) bfs(ans,mp3,mod);
    		if(i==4) bfs(ans,mp4,mod);
    		if(i==5) bfs(ans,mp5,mod);
    		if(i==6) bfs(ans,mp6,mod);
    		if(i==7) bfs(ans,mp7,mod);
    	}
    }
    struct shit{
    	int x,y;
    	bool operator<(const shit &a)	const// "This blade never gets any lighter."
    	{
    		return x<a.x;
    	}
    }f[10];
    int main()
    {
    	int i,j,n,m,t;
    	init();
    	int b[9];
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d",&n);
    		for(i=1;i<=n;i++)
    		{
    			scanf("%d",&f[i].x);
    			f[i].y=i;
    		}
    		if(n==1)	printf("0
    ");
    		else	if(n==2)
    		{
    			if(f[1].x<f[2].x)	printf("0
    ");
    			else	printf("-1
    ");
    		}
    		else
    		{
    			sort(f+1,f+1+n);
    			for(i=1;i<=n;i++)
    				b[f[i].y]=i;
    			int md[10];
    			md[1]=1;
    			for(i=2;i<=n;i++)
    				md[i]=md[i-1]*n;
    			int ans=0;
    			for(i=1;i<=n;i++)
    				ans+=(n-i)*md[b[i]];
    			if(n==3)	printf("%d
    ",mp3[ans]);
    			if(n==4)	printf("%d
    ",mp4[ans]);
    			if(n==5)	printf("%d
    ",mp5[ans]);
    			if(n==6)	printf("%d
    ",mp6[ans]);
    			if(n==7)	printf("%d
    ",mp7[ans]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Dll Hijacker
    PE文件格式学习之PE头移位
    远程线程注入shellcode笔记
    DLL注入之SHELLCODE数据转换
    vc libcurl 模拟上传文件
    Mysql uploader File
    vc 导出函数/调用
    windows 模拟用户会话创建进程
    综合一句话Shell破解
    义牛有灵舍命报恩 力拼强盗感人肺腑
  • 原文地址:https://www.cnblogs.com/bitch1319453/p/4827004.html
Copyright © 2011-2022 走看看