day12

195 阅读6分钟

RC-u3

跑团机器人

(20分)

在桌面角色扮演游戏(TRPG,俗称“跑团”)中,玩家需要掷出若干个骰子,根据掷出的结果推进游戏进度。在线上同样可以跑团,方法是由玩家们向机器人发出指令,由机器人随机产生每个需要掷出的骰子的结果。

玩家向机器人发出的指令是一个仅涉及加法和减法的表达式,即对若干个数字进行一系列加法或减法计算。这些数字可以是直接给出的非负整数(数字不超过 1000),也可以是若干个骰子掷出的结果。

“掷骰子”这个动作对应的指令格式为 xdy,表示摇动 x 个 y 面的骰子(1≤x≤1000,2≤y≤1000)。当 x 为 1 时,1 可以省略。

例如指令 2d3+3-d4 的意思是:先掷出 2 个 3 面骰子(你不必考虑现实中是否存在这样的骰子),不妨假设结果为 1 和 3,则 2d3 的结果就是两个骰子的面值之和 4;然后计算 4 + 3,得到结果为 7;再掷出 1 个 4 面骰子,不妨假设结果为 2,则计算 7 - 2 得到最终结果 5。

本题就请你计算玩家输入的指令里,不同种类的骰子需要掷出几个,以及可能得到的结果在什么区间范围内。

输入格式:

输入在一行中给出一条符合题目描述的玩家输入机器人的指令。题目保证指令长度不超过 2∗104。

输出格式:

首先输出不同种类的骰子分别需要掷出几个。每种骰子的信息占一行,依次输出骰子的面数和投掷的数量,按面数从小到大输出。

输入指令保证至少有一个骰子需要掷出。

最后一行输出两个数,表示根据输入指令可以得到的最小结果和最大结果。

同一行数字间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

d6+3d5+2-2d3+2d5

输出样例:

3 2
5 5
6 1
2 31

编译器

NO_COMPILER

代码

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N=1010;

string str;

LL eps;
LL up,down;
LL cnt[N];	//代表i面色子要用多少个 

int main()
{
	cin>>str;
	
	str="+"+str+"+";
	
	LL num=0,S=0;	
	bool flag=false;	//代表这个是不是色子 
	bool op=true;		//true代表加 false代表减 
	for (int i=0;i<str.size();i++)
	{
		auto t=str[i];
		if (t=='+' || t=='-')
		{
			if (!flag)	
			{
				if (op)	eps+=S;
				else eps-=S;
				S=0;
			}
			else
			{
				cnt[S]+=num;
				
				if (op)	
				{
					up+=num*S;
					down+=num;
				}
				else
				{
					up-=num;
					down-=num*S;
				}
				
			}
			S=0;num=0;		
			flag=false;	
			
			if (t=='+')	op=true;
			else op=false;
		}
		else if (t=='d')
		{
			if (str[i-1]=='+' || str[i-1]=='-')
				S=1;
			
			num=S;
			S=0;
			flag=true;
		}
		else
		{
			S=S*10+t-'0';
		}
	}
	
	for (int i=1;i<N;i++)
		if (cnt[i])
			cout<<i<<" "<<cnt[i]<<endl;
	
	cout<<down+eps<<" "<<up+eps;

	return 0;
}

编译器输出

a.cpp: In function ‘int main()’:
a.cpp:22:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i=0;i<str.size();i++)
               ~^~~~~~~~~~~
测试点结果测试点得分耗时内存
0答案正确85.00 ms444 KB
1答案正确14.00 ms312 KB
2答案正确14.00 ms328 KB
3答案正确25.00 ms568 KB
4答案正确24.00 ms448 KB
5答案正确25.00 ms476 KB
6答案正确14.00 ms472 KB
7答案正确16.00 ms312 KB
8答案正确14.00 ms384 KB
9答案正确14.00 ms328 KB

评测结果答案正确(20 分)

RC-u4

攻略分队

(25分)

副本是游戏里的一个特色玩法,主要为玩家带来装备、道具、游戏资源的产出,满足玩家的游戏进程。

在 MMORPG《最终幻想14》里,有一个攻略人数最大达到 56 人的副本“巴尔德西昂兵武塔”,因为有在副本里死亡不能复活、机制比较整蛊等特点,一度被玩家视作洪水猛兽。

在副本的开始,我们会遇到第一个难关:攻略的玩家要分为两组,同时讨伐副本 BOSS “欧文”和“亚特”。

已知以下信息:

  1. 玩家会组成 6 支队伍进入副本,其中第 i 队有 Vi​ 位玩家(i=1,⋯,6)。
  2. 每支队伍可能会有一些特殊角色:MT(主坦克)、工兵(负责探测陷阱)和指挥(负责指挥玩家)。

我们的任务是合理安排玩家的分组,以最大程度增加副本通过概率。分组的原则如下:

  1. 要将所有队伍分成 2 组,每支队伍必须且仅属于其中一组;
  2. 每组必须有至少一个 MT(主坦克)。

如果满足上述原则的分组方案不唯一,则按照下列规则确定唯一解:

  1. 优先选择每组有至少一个指挥和至少一个工兵的方案;
  2. 如果规则 1 无法满足,则优先选择每组至少有一个指挥的方案;
  3. 如果所有方案都不满足规则 2,或经过前 2 个规则筛选后,分组方案仍不唯一,则选择两边人数尽可能接近(即两边人数差尽可能小)的方案;
  4. 如果满足规则 3 的方案还不唯一,选择讨伐“欧文”的人数大于等于讨伐“亚特”的人数的方案;
  5. 如果满足规则 4 的方案还不唯一,选择讨伐“欧文”的队伍编号方案中最小的一个。

注:一个队伍编号方案 A={a1​<⋯<am​} 比 B={b1​<⋯<bn​} 小,当且仅当存在 1≤k≤min(m,n) 使得 ai​=bi​ 对所有 0<i<k 成立,且 ak​<bk​。

本题就请你给出满足所有分组原则的分配方案。

感谢 王宪泉 同学对规则 4 的指正,于 2022-08-04 修改

输入格式:

输入第一行给出 6 支队伍的玩家数量,即 6 个非负整数 Vi​ (0≤Vi​≤8,1≤i≤6)。队伍人数为 0 时表示队伍不存在。

随后 6 行,按队伍编号顺序,每行给出一支队伍的特殊角色,格式为 ABC,其中 A 对应 MT,B 对应工兵,C 对应指挥。三种角色对应取值 0 或 1,0 表示没有该角色,1 表示有。

注:由于可能存在一人兼任多个特殊角色的情况,所以一支队伍中的特殊角色数量有可能大于该队伍的玩家数量。

输出格式:

输出分两行,第一行输出讨伐“欧文”的队伍编号,第二行输出讨伐“亚特”的队伍编号。同一行中的编号按升序输出,以 1 个空格分隔,行首尾不得有多余空格。

如果不存在合法的方案,输出GG

输入样例1:

6 8 7 5 3 0
010
101
110
001
111
000

输出样例1:

2 3
1 4 5

输入样例2:

6 8 7 5 3 0
010
101
010
001
011
000

输出样例2:

GG