zoukankan      html  css  js  c++  java
  • 斗地主

    题目链接

    1.这一版是不能拆牌的所以花色什么用都没有

    2.A和2接在JQK后面存储不需要特判

    3.四带的是两张单牌或者两对牌(4张)

    4.顺子不带2和双王但是三带一四带二是可以带的(注意双王不算一对牌,只能算单牌)

    5.当前步数最多不超过剩余牌数,minn初始化成n,每次统计剩余牌数加上step更新minn

    6.有了5.单牌就不需要统计了

    7.除顺子外别的牌因为牌数一定,可以算出最少步数,剪个枝

    8.按牌数多少安排搜索顺序

    9.当前步数大于minn直接return

    #include<bits/stdc++.h>
    using namespace std;
    int ans=0,num[20],minn=17;
    void dfs(int step)
    {
    	if(step>=minn) return;
    	int f=0,sum=0;
    	for(int i=3;i<=15;i++)
    	{
    		if(num[i]>0) 
    		{
    			f=1;
    			sum+=num[i];
    		}
    	}
    	if(num[16]>0) sum++;
    	minn=min(minn,step+sum);
    	if(f==0) return;
    	for(int i=3;i<=14;i++)//3顺子 
    	{
    		int j=i;
    		for(;j<=14;j++)	if(num[j]<3) break;
    		j--;//j跳出来一定是不合法的,不管是>14还是num[j]<3,下同
    		for(int jj=j;jj>=i+1;jj--)
    		{
    			for(int k=i;k<=jj;k++) num[k]-=3;
    			dfs(step+1);
    			for(int k=i;k<=jj;k++) num[k]+=3;
    		}
    	}
    	for(int i=3;i<=14;i++)//2顺子 
    	{
    		int j=i;
    		for(;j<=14;j++)	if(num[j]<2) break;
    		j--;
    		for(int jj=j;jj>=i+2;jj--)
    		{
    			for(int k=i;k<=jj;k++) num[k]-=2;
    			dfs(step+1);
    			for(int k=i;k<=jj;k++) num[k]+=2;
    		}
    	}
    	for(int i=3;i<=14;i++)//单顺子 
    	{
    		int j=i;
    		for(;j<=14;j++)	if(num[j]<1) break;
    		j--;
    		for(int jj=j;jj>=i+4;jj--)
    		{
    			for(int k=i;k<=jj;k++) num[k]--;
    			dfs(step+1);
    			for(int k=i;k<=jj;k++) num[k]++;
    		}
    	}
    	if(step+sum/8>minn) return;
    	for(int i=3;i<=15;i++)//4带2 ,炸弹 
    	{
    		if(num[i]==4)
    		{
    			num[i]-=4;
    			for(int j=3;j<=16;j++)//带单 
    			{
    				if(num[j]>0)
    				for(int k=3;k<=16;k++)
    				{
    				 	if(num[k]>0&&k!=j)//带两单 
    					{
    						num[j]--;num[k]--;
    						dfs(step+1);
    						num[j]++;num[k]++;
    					}
    				} 
    				if(num[j]>=2)
    				{
    					num[j]-=2;
    					dfs(step+1);
    					num[j]+=2;
    				}
    			}
    			for(int j=3;j<=15;j++)//带双 
    			{
    				if(num[j]>=2)
    				for(int k=3;k<=15;k++)
    				if(num[k]>=2&&k!=j)
    				{
    					num[j]-=2;num[k]-=2;
    					dfs(step+1);
    					num[j]+=2;num[k]+=2;
    				}
    			}
    			dfs(step+1);//炸弹 
    			num[i]+=4;
    		}
    	}
    	if(step+sum/5>minn) return;
    	for(int i=3;i<=15;i++)//3带2 ,3带1 ,3张牌 
    	{
    		if(num[i]==3)
    		{
    			num[i]-=3;
    			for(int j=3;j<=15;j++)
    			{
    				if(num[j]>=2)
    				{
    					num[j]-=2;
    					dfs(step+1);
    					num[j]+=2;
    				}
    				if(num[j]>0)
    				{
    					num[j]--;
    					dfs(step+1);
    					num[j]++;
    				}
    			}
    			if(num[16]>0)
    			{
    				num[16]--;
    				dfs(step+1);
    				num[16]++;
    			}
    			dfs(step+1);
    			num[i]+=3;
    		}
    	}
    	if(step+sum/2>minn) return;
    	for(int i=3;i<=15;i++)//对子 
    	{
    		if(num[i]>=2)
    		{
    			num[i]-=2;
    			dfs(step+1);
    			num[i]+=2;
    		}
    	}
    }
    int main()
    {
    	int t,n;
    	cin>>t>>n;
    	while(t--)
    	{
    		memset(num,0,sizeof(num));
    		ans=0;	int a1,b1;
    		minn=n;
    		for(int i=1;i<=n;i++)
    		{
    			cin>>a1>>b1;
    			if(a1==0) num[16]++;
    			if(a1==1) num[14]++;
    			if(a1==2) num[15]++;
    			if(a1>=3&&a1<=13) num[a1]++;
    		}
    		dfs(0);
    		cout<<ans+minn<<"
    ";
    	}
    	return 0;
    }//今天是个好日子啊我的斗地主调出来了
    
  • 相关阅读:
    ffmpeg之AVFrame
    ffmpeg之samplefmt
    音视频基本概念
    cmake函数 file
    ffmpeg之AVPacket
    ffmpeg之AVFormatContext
    存储格式:packed和planar
    ffmpeg之channel_layout
    cmake函数: get_filename_component
    ffmpeg整体结构
  • 原文地址:https://www.cnblogs.com/qwq-/p/13671269.html
Copyright © 2011-2022 走看看