首页 > 专题系列 > Java解POJ > POJ 2721 Suit Distribution [解题报告] Java
2013
11-11

POJ 2721 Suit Distribution [解题报告] Java

Suit Distribution

问题描述 :

Bridge is a 4-player (two teams of two) card game with many complicated conventions that even experienced players have difficulty keeping track of. Fortunately, we are not interested in these conventions for this problem. In fact, it is not even important if you understand how to play the game.

What is important to know is that the way the cards are distributed among your two opponents often determine whether you will be successful in your game. For example, suppose you and your partner hold 8 spades. The remaining 5 spades are held by your opponents (since there are 13 cards in each suit) and can be distributed in the following ways: 0-5, 1-4, 2-3. Notice that a 0-5 “split” can be realized in two ways—opponent 1 has no spade and opponent 2 has 5 spades, or vice versa.

Good bridge players know that the best line of play often depends on the distribution. Sometimes good players can “read their opponents’ cards” and determine the distribution, but sometimes even good players have to guess. In those cases, knowing the probability of the different distributions would be useful in making an educated guess.

You can assume that the 52 cards in a deck are dealt out randomly to 4 players, so that every player has 13 cards, and that you know which 26 cards your team holds.

输入:

The input consists of a number of cases. Each case consists of two integers a, b (0 <= a, b <= 13, a + b <= 13). The input is terminated by a = b = -1.

输出:

For each case, print the probability of a split of a+b cards so that one opponent has a cards and the other has b cards in the format as shown in the sample output. You may assume that the remaining cards in the suit are held by you and your partner. Output the probabilities to 8 decimal places.

样例输入:

2 2
3 3
4 2
-1 -1

样例输出:

2-2 split: 0.40695652
3-3 split: 0.35527950
4-2 split: 0.48447205

解题代码:

/* @author: */
import java.util.Scanner;
import java.util.Arrays;
public class Main{
   private int a,b;
   private double f1,f2,f3,f4,f5,f6,t1,t2,t3,t4,t5,t6;

   public Main(int a,int b){
    this.a=a;
    this.b=b;
    f1=13-a+1;f2=13-b+1;f3=1;
    t1=13;t2=13;t3=a+b;
    f4=1;f5=1;f6=26-(a+b)+1;
    t4=a;t5=b;t6=26;
   }

  

 public static void main(String args[]){
  Scanner sc=new Scanner(System.in);
  while(sc.hasNext()){
    int a=sc.nextInt();
    int b=sc.nextInt();
    if(a< 0) break;
    
    Main m=new Main(a,b);
    System.out.printf("%d-%d split: %10.8f\n",a,b,m.doIt());
  }   
 }

 private int check()
  {
    if(f1<=t1||f2<=t2||f3<=t3||f4<=t4||f5<=t5||f6<=t6)return 1;
    return 0;
  }    
      
 public double doIt(){
        double x=1;
        while(check()!=0)
        {
            if(f1<=t1){x*=f1;f1++;}
            if(f2<=t2){x*=f2;f2++;}
            if(f3<=t3){x*=f3;f3++;}
            if(f4<=t4){x/=f4;f4++;}
            if(f5<=t5){x/=f5;f5++;}
            if(f6<=t6){x/=f6;f6++;}    
        }    
        if(a!=b)x*=2;
       return x;
    }    
}

  1. 在方法1里面:

    //遍历所有的边,计算入度
    for(int i=0; i<V; i++)
    {
    degree = 0;
    for (j = adj .begin(); j != adj .end(); ++j)
    {
    degree[*j]++;
    }
    }

    为什么每遍历一条链表,要首先将每个链表头的顶点的入度置为0呢?
    比如顶点5,若在顶点1、2、3、4的链表中出现过顶点5,那么要增加顶点5的入度,但是在遍历顶点5的链表时,又将顶点5的入度置为0了,那之前的从顶点1234到顶点5的边不是都没了吗?

  2. #include <cstdio>

    int main() {
    //answer must be odd
    int n, u, d;
    while(scanf("%d%d%d",&n,&u,&d)==3 && n>0) {
    if(n<=u) { puts("1"); continue; }
    n-=u; u-=d; n+=u-1; n/=u;
    n<<=1, ++n;
    printf("%dn",n);
    }
    return 0;
    }