站外题求助(玄三关)
  • 板块学术版
  • 楼主shy_lihui
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/8/28 19:17
  • 上次更新2024/8/28 21:27:03
查看原帖
站外题求助(玄三关)
1053122
shy_lihui楼主2024/8/28 19:17

题面

乌龟对对碰

33DAI 最近在看一个乌龟对对碰游戏。游戏规则如下(下面所有的“乌龟”指的都是乌龟玩具):

游戏道具

有一个 3×33×3 的九宫格棋盘。编号如下:

123
456
789

有 nn 个乌龟,编号 1∼n1\sim n,每个乌龟都有一个颜色,第 ii 个乌龟的颜色用一个整数 aia_i 表示,颜色有 1010 种,分别对应到数字 0∼90\sim 9。 有一个幸运颜色 xx(0∼90\sim 9 中的一种)

游戏流程

第一步、初始的乌龟数量限制为 mm。

第二步、按编号从小到大的顺序,依次在还存在的乌龟中拿乌龟,每拿一个,乌龟计数器 +1+1。每个乌龟都放到一个空格子中,如果有多个空格子,放在编号最小的空格子中。

第三步、放的过程中,如果当前乌龟颜色是幸运颜色,那么乌龟数量限制 +1+1。

第四步、放的过程中,如果已经放满了、或者乌龟计数器达到了乌龟数量限制,就开始进行结算。

第五步、结算后,如果乌龟计数器小于乌龟数量限制,那么会回到第二步,继续拿乌龟放到棋盘中。

结算规则

编号小的规则优先级更高,每个操作完成后都会再次从小到大检查所有规则,直到所有规则都不满足为止。

  1. 【全家福】如果当前棋盘上的乌龟颜色全都不一样,把棋盘上所有乌龟销毁,乌龟数量限制 +8+8

  2. 【同行】如果当前棋盘上 33 只颜色一样的乌龟在同一行,把这 33 只乌龟销毁,乌龟数量限制 +2+2

  3. 【同列】如果当前棋盘上 33 只颜色一样的乌龟在同一列,把这 33 只乌龟销毁,乌龟数量限制 +2+2

  4. 【对角线1】如果当前棋盘上 33 只颜色一样的乌龟在 1,5,91,5,9 这三个位置,把这 33 只乌龟销毁,乌龟数量限制 +2+2

  5. 【对角线2】如果当前棋盘上 33 只颜色一样的乌龟在 3,5,73,5,7 这三个位置,把这 33 只乌龟销毁,乌龟数量限制 +2+2

  6. 【碰】从 1∼9 1\sim 9 依次检查棋盘上的每个位置 ii,如果有另一个位置 jj 上的乌龟颜色与 ii 一致(如果有多个位置,挑选最小的 jj),销毁这两只乌龟,乌龟数量限制 +1$ 常见的结算规则还有清盘的奖励,但本题不考虑。

输入格式

第一行为整数 n,m,xn,m,x。

第二行为一个长度为 nn 的字符串,第 ii 个字符为 aia_i

输出格式

输出最终乌龟计数器的大小。

我的代码

#include<bits/stdc++.h>
using namespace std;
int n;//乌龟数量 
int m;//乌龟数量限制
int cnt;//乌龟计数器 
int x;//幸运颜色
int a[15];//棋盘


bool check1()//判断【全家福】是否成立 (变化)
{
   int s=a[1];//备份
   for(int i=2;i<=9;i++) //扫一遍 
   {
   	if(s==a[i] || a[i]==-1) //如果有相同 或这个位置为空 
   	{
   		return 0; //返回不存在 
   	}
   }
   a[1]=a[2]=a[3]=a[4]=a[5]=a[6]=a[7]=a[8]=a[9]=-1; //数组全部变成-1 
   m+=8;//乌龟数量限制+8
   return 1; //返回1存在 
}


bool check2()//判断【同行】是否存在(变化) 
{
   bool f=0;//标记是否出现过同行
   if(a[1]==a[2] && a[2]==a[3] && a[1]!=-1 && a[2]!=-1 && a[3]!=-1) //如果第一行相等且没有-1 
   {
   	m+=2;//乌龟数量限制+2
   	f=1;//标记出现 
   	a[1]=a[2]=a[3]=-1;//变成-1 
   }
   if(a[4]==a[5] && a[5]==a[6] && a[4]!=-1 && a[5]!=-1 && a[6]!=-1) //如果第二行相等且没有-1 
   {
   	m+=2;//乌龟数量限制+2
   	f=1;//标记出现 
   	a[4]=a[5]=a[6]=-1;//变成-1 
   }
   if(a[7]==a[8] && a[8]==a[9] && a[7]!=-1 && a[8]!=-1 && a[9]!=-1) //如果第三行相等且没有-1 
   {
   	m+=2;//乌龟数量限制+2
   	f=1;//标记出现 
   	a[7]=a[8]=a[9]=-1;//变成-1 
   }
   return f; //返回是否存在 
}


bool check3() //判断【同列】是否存在(变化) 
{
   bool f=0;//标记是否出现过同列
   if(a[1]==a[4] && a[4]==a[7] && a[1]!=-1 && a[4]!=-1 && a[7]!=-1) //如果第一列相等且没有-1 
   {
   	m+=2;//乌龟数量限制+2
   	f=1;//标记出现 
   	a[1]=a[4]=a[7]=-1;//变成-1 
   }
   if(a[2]==a[5] && a[5]==a[8] && a[2]!=-1 && a[5]!=-1 && a[8]!=-1) //如果第二列相等且没有-1 
   {
   	m+=2;//乌龟数量限制+2
   	f=1;//标记出现 
   	a[2]=a[5]=a[8]=-1;//变成-1 
   }
   if(a[3]==a[6] && a[6]==a[9] && a[3]!=-1 && a[6]!=-1 && a[9]!=-1) //如果第三列相等且没有-1 
   {
   	m+=2;//乌龟数量限制+2
   	f=1;//标记出现 
   	a[3]=a[6]=a[9]=-1;//变成-1 
   }
   return f; //返回是否存在 
}

bool check4()  //判断【对角线1】是否存在(变化) 
{
   if(a[1]==a[5] && a[5]==a[9] && a[1]!=-1 && a[5]!=-1 && a[9]!=-1)//如果这条对角线相等且没有-1 
   {
   	m+=2;//乌龟数量限制+2
   	a[1]=a[5]=a[9]=-1;//变成-1 
   	return 1;//返回存在 
   }
   return 0; //返回不存在 
}


bool check5()  //判断【对角线2】是否存在(变化) 
{
   if(a[3]==a[5] && a[5]==a[7] && a[3]!=-1 && a[5]!=-1 && a[7]!=-1)//如果这条对角线相等且没有-1 
   {
   	m+=2;//乌龟数量限制+2
   	a[3]=a[5]=a[7]=-1;//变成-1 
   	return 1;//返回存在 
   }
   return 0;//返回不存在 
}

bool check6() //判断【碰】是否存在(变化) 
{
   bool f;//标记是否存在 
   for(int i=1;i<=9;i++)
   {
   	for(int j=1;j<=9;j++)
   	{
   		if(a[i]==a[j] && i!=j && a[i]!=-1 && a[j]!=-1)//如果合法
   		{
   			a[i]=a[j]=-1;//变成-1; 
   			m++;//乌龟限制数量+1
   			return 1;//返回存在 
   		}
   	}
   }
   return 0;//返回不存在 
} 





void accounts()  //结算函数 
{
   if(check1())//如果【全家福】成立
   {
   	return;//退出整个结算函数 
   }
   if(check2())//如果【同行】成立 
   {
   	accounts();//结算 
   }
   if(check3())//如果【同列】成立 
   {
   	accounts();//结算 
   }
   if(check4())//如果【对角线1】成立 
   {
   	accounts();//结算 
   }
   if(check5())//如果【对角线2】成立 
   {
   	accounts();//结算 
   }
   if(check6())//如果【碰】成立 
   {
   	accounts();//结算 
   }
}


int main()
{
   freopen("turtle.in","r",stdin);
   freopen("turtle.out","w",stdout);
   ios::sync_with_stdio(false);
   cin.tie(0);
   cin>>n>>m>>x;
   a[1]=a[2]=a[3]=a[4]=a[5]=a[6]=a[7]=a[8]=a[9]=-1; //将数组全部变成-1 
   while(n--)
   {
   	if(cnt>=m)//如果计数器达到限制 
   	{
   		break;//结束循环 
   	}
   	char c;
   	int p;
   	cin>>c;//输入乌龟编号
   	p=c-'0';
   	if(p==x) //如果遇到幸运颜色 
   	{
   		m++;//乌龟数量限制+1
   	}
   	cnt++;//乌龟计数器+1 
   	bool flag=0;//标记是否存入棋盘 
   	for(int i=1;i<10;i++) //遍历整个棋盘 
   	{
   		if(a[i]==-1) //如果遇到空位 
   		{
   			a[i]=p; //存入
   			flag=1;//标记已存入
   			break; //退出 
   		}
   	}
   	if(flag==0)//如果存满了 
   	{
   		accounts();//结算
   		//重新存入 
   		for(int i=1;i<10;i++) //遍历整个棋盘 
   		{
   			if(a[i]==-1) //如果遇到空位 
   			{
   				a[i]=p; //存入
   				break; //退出
   			}
   		}
   	}
   }
   cout<<cnt;
   return 0;
}
2024/8/28 19:17
加载中...