3470 整理扑克牌

题目链接

思路1.简单模拟+贪心,每次选择数目最少的牌,用特俗牌替代它,组合成一副牌,直到特殊牌数目为0,然后可以再组合出所剩最少数目副牌。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
typedef long long  ll;
const int maxm=1010;
int b,num[55],Min,idx;
void getmin(){
    Min=num[1],idx=1;
    for(int i=1;i<=54;++i) {
            if(num[i]<Min){
                Min=num[i];
                idx=i;
            }
        }
}
bool remove(int x){
    b-=x;
    for(int i=1;i<=54;++i){
        if(i!=idx) {
            num[i]-=x;
        }
        if(num[i]<0) return 0;
    }
    return 1;
}
int main(){
    while(scanf("%d",&b)==1){
        for(int i=1;i<=54;++i) scanf("%d",&num[i]);
        int ans=0;
        while(b>0){
            getmin();
            int x=min(b,Min);
            if(remove(x)) ++ans;
        }
        getmin();
        if(Min>0) ans+=Min;
        printf("%d\n",ans);
    }
    return 0;
}

结果超时

思路2.对ans进行二分,如何判断能否组合出ans副牌是关键

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
typedef long long  ll;
const int maxm=1010;
int b,num[55];
bool ok(int x){
    int s=0;
    for(int i=0;i<54;++i){
        if(num[i]<s) return 0;
        s+=max(0,x-num[i]);
        if(s> b) return 0;
    }
    return 1;
}
int main(){
    while(scanf("%d",&b)==1){
        for(int i=0;i<54;++i) scanf("%d",&num[i]);
        sort(num,num+54);
        int  l=0,r=1000000000;
        while(r-l>1){
            int m=(r+l)>>1;
            if(ok(m)) l=m;
            else r=m;
        }
        printf("%d\n",l);
    }
    return 0;
}
### Java 实现扑克牌整理算法 在Java中实现扑克牌整理功能涉及定义卡片(Card)、玩家(Player),以及管理游戏流程(Game)的类。下面展示如何通过这些组件来构建一个简单的扑克牌整理机制。 #### 定义 Card 类 每张卡牌由其面值(value)和花色(suit)唯一确定,并可以重写`toString()`方法以便于打印输出。 ```java public class Card { private final String suit; // 花色 private final int value; // 数字 public Card(String suit, int value){ this.suit = suit; this.value = value; } @Override public String toString(){ return "Card{" + "suit='" + suit + '\'' + ", value=" + value + '}'; } } ``` #### 创建 Player 类 每位参与者拥有一手牌(hand),即一组`Card`实例列表,可以通过添加新获得的卡牌到手中或者移除已打出的卡牌来进行更新。 ```java import java.util.ArrayList; public class Player { private ArrayList<Card> hand = new ArrayList<>(); private String name; public Player(String name){ this.name = name; } public void addCardToHand(Card card){ hand.add(card); } public void sortCards() { hand.sort((c1, c2) -> Integer.compare(c1.getValue(), c2.getValue())); } public String getName(){return name;} public ArrayList<Card> getHand(){return hand;} } ``` 注意,在这里增加了`sortCards()`函数用于对手中的牌按照数值大小进行排序[^2]。 #### 构建 Game 类 此部分负责初始化一副完整的52张标准扑克牌,执行洗牌动作,向各玩家分配初始手牌,同时提供逻辑控制整个对局过程的功能。 ```java import java.util.Collections; import java.util.LinkedList; import java.util.List; public class Game { List<Player> players = new LinkedList<>(); public static List<Card> createDeck(){ List<String> suits = Arrays.asList("Spades", "Hearts", "Diamonds", "Clubs"); List<Integer> values = IntStream.rangeClosed(1, 13).boxed().collect(Collectors.toList()); List<Card> deck = new ArrayList<>(52); for (String s : suits) for(int v : values) deck.add(new Card(s,v)); Collections.shuffle(deck); // Shuffle the cards. return deck; } public void dealInitialHands(List<Card> deck,int numPlayers){ while (!deck.isEmpty()){ for (int i=0;i<numPlayers && !deck.isEmpty();i++){ players.get(i % numPlayers).addCardToHand(deck.remove(0)); } } } public void startGame(int numberOfPlayers){ List<Card> deck = createDeck(); for (int i=0 ; i<numberOfPlayers ; ++i ) players.add(new Player("Player "+(i+1))); dealInitialHands(deck,numberOfPlayers); System.out.println("Dealt initial hands."); } } ``` 上述代码片段展示了创建一副有序排列的标准扑克牌的过程,随后对其进行随机化处理以模拟真实世界里的洗牌行为;接着根据指定数量的参与人数平均分发给各个选手作为起始阶段的手牌[^1]。 最后,为了完成一次完整的回合制游戏操作,还需要编写额外的方法用来接收用户的输入指令(比如选择要出哪几张牌)、判断当前轮次是否结束以及其他必要的业务规则验证等。不过这部分具体细节会依据实际应用场景有所不同,因此在此不做赘述。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值