【发布时间】:2019-11-07 03:04:31
【问题描述】:
我正在尝试解决在线法官问题。问题描述:
这是原来的问题:https://www.urionlinejudge.com.br/judge/en/problems/view/1090
这里是输入的完整列表: http://maratona.ime.usp.br/hist/2008/primeira-fase/testset2008/principal/G.in (警告:巨大的 ~10mb 文件)
输出:http://maratona.ime.usp.br/hist/2008/primeira-fase/testset2008/principal/G.sol
- Set 是一种纸牌游戏,其中每张纸牌可能有一个、两个或三个数字。
- 一张给定卡片中的所有数字都是相等的。
- 图形可以是圆形、正方形或三角形。
- 每张卡片因此具有两个特征:数字的数量和类型图。
一组是一组三张卡片,对于每个特征(number 和 figure): 三张卡片相等或三张卡片不同。
- (a) 是一个有效的集合,因为所有卡片都具有相同的图形类型并且 他们都有不同的数字。
- (b), 图形的类型和图形的数量都不同, 制作也是一个有效的集合。另一方面,
- (c) 不是有效集合, 因为最后两张牌有相同的数字,这与 第一张卡片中的人物。
- (d)和(e)有效,图类型相同,图号相同。
对于非常大的牌组(给定的牌数),找到可以找到最多组数的最佳方法可能会很麻烦。
在某些情况下,通过按此特定顺序删除,所有:
- 图形类型相同,数量不同。
- 不同的图形类型,不同的数量。
- 相同的图形类型,相同的数量。
是最佳方法,但在某些情况下不是,在其他情况下,按以下顺序删除:
- 不同的图形类型,不同的数量。
- 图形类型相同,数量不同。
- 相同的图形类型,相同的数量。
是最佳方法,最后,在其他情况下删除:
相同的图形类型,相同的数量......等等是最好的最优方法。
我可以暴力破解它并执行所有搜索并使用找到最多的搜索,但这显然并不理想。现在,我一直试图找出在特定情况下使一种方法比另一种方法更好的潜在问题,但我就是想不通。我试过检查even/odd每种卡的数量,但没有正确和错误方法之间的模式。
关于如何找到最佳方法的任何想法?代码:
#include <iostream>
enum CardType
{
SQUARE_ONE,
SQUARE_TWO,
SQUARE_THREE,
CIRCLE_ONE,
CIRCLE_TWO,
CIRCLE_THREE,
TRIANGLE_ONE,
TRIANGLE_TWO,
TRIANGLE_THREE
};
constexpr int FIGURE_MAX = 9;
class Set
{
private:
int m_Amount {0};
public:
int GetAmount() const { return m_Amount; }
private:
void IncreaseAmountOfMatches() {m_Amount++;}
int m_arrCards[FIGURE_MAX] {0};
public:
void ReadCards(int N);
void PerformMatching();
void PerformMatching_SameType_DiffAmount();
void PerformMatching_DiffType_DiffAmount();
void PerformMatching_SameType_SameAmount();
void Reset();
private:
CardType GetCardByName(const std::string& name);
inline void DecreaseType(CardType type1, CardType type2, CardType type3);
inline void DecreaseThreeOfExactlyEqualType(CardType type);
};
void Set::Reset()
{
m_Amount = 0;
for(int i{0}; i<FIGURE_MAX; i++) {
m_arrCards[i] = 0;
}
}
void Set::ReadCards(int N)
{
Reset();
static std::string name;
for(int i{0}; i<N; i++){
std::getline(std::cin, name);
m_arrCards[GetCardByName(name)]++;
}
}
inline void Set::DecreaseThreeOfExactlyEqualType(CardType type)
{
if(m_arrCards[type] >= 3) {
m_arrCards[type] -= 3;
IncreaseAmountOfMatches();
}
}
inline void Set::DecreaseType(CardType type1, CardType type2, CardType type3)
{
if(m_arrCards[type1] && m_arrCards[type2] && m_arrCards[type3])
{
m_arrCards[type1]--;
m_arrCards[type2]--;
m_arrCards[type3]--;
IncreaseAmountOfMatches();
}
}
void Set::PerformMatching_SameType_DiffAmount()
{
while(true) //SAMETYPE, DIFFAMOUNT
{
int currentAmount = GetAmount();
//Same Square
DecreaseType(SQUARE_ONE, SQUARE_TWO, SQUARE_THREE);
//Same Circle
DecreaseType(CIRCLE_ONE, CIRCLE_TWO, CIRCLE_THREE);
//Same Triangle
DecreaseType(TRIANGLE_ONE, TRIANGLE_TWO, TRIANGLE_THREE);
if(currentAmount == GetAmount()) {
break;
}
}
}
void Set::PerformMatching_DiffType_DiffAmount()
{
while(true) //DIFFTYPE, DIFFAMOUNT
{
const int currentAmount = GetAmount();
//Different Squares
DecreaseType(SQUARE_ONE, CIRCLE_TWO, TRIANGLE_THREE);
DecreaseType(SQUARE_ONE, TRIANGLE_THREE, CIRCLE_TWO);
DecreaseType(SQUARE_TWO, CIRCLE_ONE, TRIANGLE_THREE);
DecreaseType(SQUARE_TWO, CIRCLE_THREE, TRIANGLE_ONE);
DecreaseType(SQUARE_THREE, CIRCLE_ONE, TRIANGLE_TWO);
DecreaseType(SQUARE_THREE, CIRCLE_TWO, TRIANGLE_ONE);
//Different Circles
DecreaseType(CIRCLE_ONE, SQUARE_TWO, TRIANGLE_THREE);
DecreaseType(CIRCLE_ONE, SQUARE_THREE, TRIANGLE_TWO);
DecreaseType(CIRCLE_TWO, SQUARE_ONE, TRIANGLE_THREE);
DecreaseType(CIRCLE_TWO, SQUARE_THREE, TRIANGLE_ONE);
DecreaseType(CIRCLE_THREE, SQUARE_TWO, TRIANGLE_ONE);
DecreaseType(CIRCLE_THREE, SQUARE_ONE, TRIANGLE_TWO);
//Different Triangles
DecreaseType(TRIANGLE_ONE, SQUARE_TWO, CIRCLE_THREE);
DecreaseType(TRIANGLE_ONE, SQUARE_THREE, CIRCLE_TWO);
DecreaseType(TRIANGLE_TWO, SQUARE_ONE, CIRCLE_THREE);
DecreaseType(TRIANGLE_TWO, SQUARE_THREE, CIRCLE_ONE);
DecreaseType(TRIANGLE_THREE, SQUARE_ONE, CIRCLE_TWO);
DecreaseType(TRIANGLE_THREE, SQUARE_TWO, CIRCLE_ONE);
//No more matches available
if(currentAmount == GetAmount()) {
break;
}
}
}
void Set::PerformMatching_SameType_SameAmount()
{
while(true)//SAMETYPE, SAMAMOUNT
{
int currentAmount = GetAmount();
DecreaseThreeOfExactlyEqualType(SQUARE_ONE);
DecreaseThreeOfExactlyEqualType(SQUARE_TWO);
DecreaseThreeOfExactlyEqualType(SQUARE_THREE);
DecreaseThreeOfExactlyEqualType(CIRCLE_ONE);
DecreaseThreeOfExactlyEqualType(CIRCLE_TWO);
DecreaseThreeOfExactlyEqualType(CIRCLE_THREE);
DecreaseThreeOfExactlyEqualType(TRIANGLE_ONE);
DecreaseThreeOfExactlyEqualType(TRIANGLE_TWO);
DecreaseThreeOfExactlyEqualType(TRIANGLE_THREE);
if(currentAmount == GetAmount()) {
break;
}
}
}
void Set::PerformMatching()
{
//how to know the best approach?
bool bestApproach = true; //what to do here?
if(bestApproach) //.....
{
PerformMatching_SameType_DiffAmount();
PerformMatching_DiffType_DiffAmount();
}
else
{
PerformMatching_DiffType_DiffAmount();
PerformMatching_SameType_DiffAmount();
}
PerformMatching_SameType_SameAmount();
}
CardType Set::GetCardByName(const std::string& name)
{
if(!name.compare("um quadrado")) return CardType::SQUARE_ONE;
if(!name.compare("dois quadrados")) return CardType::SQUARE_TWO;
if(!name.compare("tres quadrados")) return CardType::SQUARE_THREE;
if(!name.compare("um circulo")) return CardType::CIRCLE_ONE;
if(!name.compare("dois circulos")) return CardType::CIRCLE_TWO;
if(!name.compare("tres circulos")) return CardType::CIRCLE_THREE;
if(!name.compare("um triangulo")) return CardType::TRIANGLE_ONE;
if(!name.compare("dois triangulos")) return CardType::TRIANGLE_TWO;
return CardType::TRIANGLE_THREE;
}
int main()
{
static int cardAmount {0};
Set gameInstance;
while(true)
{
std::cin >> cardAmount;
std::cin.ignore();
if(cardAmount == 0) {
break;
}
gameInstance.ReadCards(cardAmount);
gameInstance.PerformMatching();
std::cout << gameInstance.GetAmount() << "\n";
}
return 0;
}
【问题讨论】:
-
一副牌的数量限制是多少?预期的时间复杂度是多少?你能分享原始问题的链接吗?
-
我刚刚注意到,在您的列表中,您忘记提及不同的图形类型,相同的数量。据我了解,这也应该是一个有效的组合?
-
@ViníciusMagalhãesHorta 是的,会的。如果数字都不同,但数量总是相同的,那就是一组。从问题:“一组是一组三张卡片,对于每个特征(数字和图形),三张卡片相等或三张卡片不同。”
-
@ViníciusMagalhãesHorta 是的,它是一组。对于每个数字,它们都是不同的。对于每个数字,它们都是相同的。根据我上面粘贴的问题的定义,这使它成为一个集合。这种缺乏对问题规则的理解很容易导致缺乏统一的解决方案。我对 Set 游戏并不陌生。
-
@sweenish,我终于解决了这个问题。你是对的
different figure type, same amount确实是一组卡片.... w-o-w!我再也不会这么快地忽略别人告诉我的事情了。对不起。
标签: c++