google jam 大赛 PlayCards 源码/另放分:)

zez 2005-12-13 01:18:16
可惜的是,topcoder 服务器太烂... 提交了一个小时,一直Time out..愣是没提交上.. 郁闷至极

import java.util.ArrayList;
/**
* @author zez
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class PlayCards {

private int maxCardsNum = 0;
private int tempMaxCardsNum = 0;

private ArrayList runNumListList = new ArrayList(); //所有行数组
private ArrayList setNumListList = new ArrayList(); //所有列数组
private ArrayList allCrossNumList = new ArrayList();// all num list
private ArrayList crossNumList = new ArrayList(); //cross num
private class CrossNum{
public int crossnum = 0; //共享数
public ArrayList setNums = null; //行
public ArrayList runNums = null; //列
public CrossNum(int num){
crossnum = num;
}
}


/*转换为数字 1--40 */
private void covertCards(String[] cards){
int length = cards.length;
String num;
char suit;
int tempNum;
CrossNum tempCrossNum;

for(int i=0 ;i < length; i++){
num = cards[i].substring(0,cards[i].indexOf(" "));
suit = cards[i].charAt(2);
tempNum = Integer.parseInt(num);
/*'S', 'H', 'D', or 'C'.*/
switch (suit){
case 'H':
tempNum = tempNum+10;
break;
case 'D':
tempNum = tempNum+20;
break;
case 'C':
tempNum = tempNum+30;
break;
default:
break;
}
/// System.out.print(tempNum);
tempCrossNum = new CrossNum(tempNum);
allCrossNumList.add(tempCrossNum);
}
/*for(int i=0 ;i < length; i++){
System.out.println(((CrossNum)crossNumList.get(i)).crossnum);
}*/
}
/*获取所有 Set 和 Run*/
private void countSetAndRun(){
int length = allCrossNumList.size();
int j;
ArrayList tempRun;

for(int i=0; i< length-2;){
/*三个连续数*/
if(((CrossNum)allCrossNumList.get(i)).crossnum +1 == ((CrossNum)allCrossNumList.get(i+1)).crossnum && ((CrossNum)allCrossNumList.get(i+1)).crossnum+1 == ((CrossNum)allCrossNumList.get(i+2)).crossnum){
tempRun = new ArrayList();
runNumListList.add(tempRun);
tempRun.add((CrossNum)allCrossNumList.get(i));
tempRun.add((CrossNum)allCrossNumList.get(i+1));
tempRun.add((CrossNum)allCrossNumList.get(i+2));
((CrossNum)allCrossNumList.get(i)).runNums = tempRun;
((CrossNum)allCrossNumList.get(i+1)).runNums = tempRun;
((CrossNum)allCrossNumList.get(i+2)).runNums = tempRun;
/*add to crossnum list*/

j=i+2;
while(j<length-1 && ((CrossNum)allCrossNumList.get(j+1)).crossnum == ((CrossNum)allCrossNumList.get(j)).crossnum+1){
tempRun.add((CrossNum)allCrossNumList.get(j+1));
((CrossNum)allCrossNumList.get(j+1)).runNums = tempRun;
j++;
}
i=j;
}
else{
i++;
}
}
ArrayList[] tempSetArray = new ArrayList[10];
for(int i = 0; i<10; i++){
tempSetArray[i]=new ArrayList();
}

for(int i = 0; i<length; i++){
//System.out.println("((CrossNum)allCrossNumList.get(i)).crossnum "+((CrossNum)allCrossNumList.get(i)).crossnum);

tempSetArray[(((CrossNum)allCrossNumList.get(i)).crossnum-1) %10].add((CrossNum)allCrossNumList.get(i));
}
for(int i = 0; i<10; i++){
if(tempSetArray[i].size()>=3){
setNumListList.add(tempSetArray[i]);
for(int k=0;k<tempSetArray[i].size();k++){
((CrossNum)(tempSetArray[i].get(k))).setNums = tempSetArray[i];
}
}
}
}
/*判断数组中是否有这个数num
private boolean isInArray(ArrayList arry,int num){
int length = arry.size();
for(int i=0 ;i<length; i++){
if(((Integer)arry.get(i)).intValue() == num){
return true;
}
}
return false;
}
*/
private void getCrossNums(){
int length = allCrossNumList.size();
for(int i=0;i<length;i++){
if(null != ((CrossNum)(allCrossNumList.get(i))).setNums && null != ((CrossNum)(allCrossNumList.get(i))).runNums){
crossNumList.add(allCrossNumList.get(i));
}
}
}

private void countMaxCards(){
for(int i=0;i<runNumListList.size()&& ((ArrayList)runNumListList.get(i)).size()>=3;i++){
tempMaxCardsNum+= ((ArrayList)runNumListList.get(i)).size();
}
for(int j=0;j<setNumListList.size()&& ((ArrayList)setNumListList.get(j)).size()>=3;j++){
tempMaxCardsNum+= ((ArrayList)setNumListList.get(j)).size();
}

if(tempMaxCardsNum> maxCardsNum)
{
maxCardsNum = tempMaxCardsNum;
}
tempMaxCardsNum=0;
}
private void countMaxCards(int i){
CrossNum tempCrossNum;
tempCrossNum = (CrossNum)crossNumList.get(i);
if(i==0){
(tempCrossNum).setNums.remove(tempCrossNum);
countMaxCards();
(tempCrossNum).runNums.remove(tempCrossNum);
tempCrossNum.setNums.add(tempCrossNum);
countMaxCards();

return;
}else{
(tempCrossNum).setNums.remove(tempCrossNum);
countMaxCards(i-1);
(tempCrossNum).runNums.remove(tempCrossNum);
tempCrossNum.setNums.add(tempCrossNum);
countMaxCards(i-1);
}

}
/*cards {"1 S", "2 S", "3 S"}*/
public int maxCards(String[] cards){
if(cards.length < 3)
{
return 0;
}

covertCards(cards);

countSetAndRun();

getCrossNums();
maxCardsNum = 0;
if(crossNumList.size()>0){
countMaxCards(crossNumList.size()-1);
}
else
{
countMaxCards();
}
return maxCardsNum;
}
public static void main(String[] args) {

PlayCards pc = new PlayCards();
String[] cards ={"1 S", "2 S", "10 S", "5 S", "8 S",
"3 H", "9 H", "6 H", "5 H", "4 H",
"10 D", "5 D", "7 D", "4 D", "1 D",
"2 C", "4 C", "5 C", "6 C", "7 C"};

//String[] cards={"1 S", "2 S"};
pc.maxCards(cards);
System.out.println("maxCardsNum "+ pc.maxCardsNum);
}
}
...全文
388 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
burn304 2005-12-13
  • 打赏
  • 举报
回复
学习ING....
umljsp 2005-12-13
  • 打赏
  • 举报
回复
楼主果真强人,惭愧惭愧!
zez 2005-12-13
  • 打赏
  • 举报
回复
忽然想起,源码中有个bug
计算 同花顺的时候没有考虑是否同花...
if(((CrossNum)allCrossNumList.get(i)).crossnum +1 == ((CrossNum)allCrossNumList.get(i+1)).crossnum && ((CrossNum)allCrossNumList.get(i+1)).crossnum+1 == ((CrossNum)allCrossNumList.get(i+2)).crossnum)
以及下面的判断..

应添加判断每个数 /10 都相等:
zez 2005-12-13
  • 打赏
  • 举报
回复
呵呵,我的思路是这样.
先把牌转换成类 CrossNum (假设所有数字都是交叉点)
只有三个数据,没有方法(用C用多了,老想到数据结构:)
private class CrossNum{
public int crossnum = 0; // 数字,把牌转换为 1-40 的数,不同花色,十位不同
public ArrayList setNums = null; //行, 此数字所在的 行,即题中的 run
public ArrayList runNums = null; //列, 此数字所在的 列,即题中的set,
//如果都不为空,就是交叉点了.. 呵呵,这就是关键
public CrossNum(int num){ //构造函数.. 无他.
crossnum = num;
}
}
然后 把所有的 同花顺 放到一个 List中, 每个同花顺也是一个List
对于 列 也这么处理
处理的同时, 给每个数也即 CrossNum中 setNums 和runNums赋值为所在的行和列.

处理完毕,查一下所有的 行,和列,只要 两个都不为空,就是真正的 交叉点. 保存起来..

然后递归处理 保存的 交叉点, 先使之属于行中,计算一次总体长度,再修改为属于列,再计算一次,记录最大值..
递归完,就处理完了,返回结果:)

呵呵,没有详细测试,可能里面还有bug... 不过大体思路就是这样的..
treeroot 2005-12-13
  • 打赏
  • 举报
回复
真的是动态规划,理论性太强了
treeroot 2005-12-13
  • 打赏
  • 举报
回复
我以为是求有多少中组合方法呢
rootcn 2005-12-13
  • 打赏
  • 举报
回复
我也做了这道题, 写了两个方法,
countRow(),
所有行内(同一花色,连续数目不小于3)连续的牌数之和,
countColumn()
所有列(同一数,不同花色,连续数目不小于3)连续牌数之和

在计算所有交叉点的时候, 理不清, 总有一些情况漏掉.
楼主能大概讲解一下这种情况的原理么.

1 2 4 5 10
2 3 5 6 8
2 3 4 5 9
3 4 5 7 8
blueindead 2005-12-13
  • 打赏
  • 举报
回复
topcoder在测试训练场的时候,有一道题目和那道寻路的算法有点类似,就是那道左撇子的题目。只不过控制方转到了内部,不知道大家有没有,做我们那组题目的?
blueindead 2005-12-13
  • 打赏
  • 举报
回复
我那道题目是超级简单的一道,是一道高中的题目,问有不同的篮子,一些相同的球,每个篮子有一定容量,问有几种方法把球全放进篮子(球是一样的,最多5个篮子)。

我同学那道题目比较难,是一道寻路的算法,也需要用到递归。
zez 2005-12-13
  • 打赏
  • 举报
回复
呵呵,我没那么厉害,我用了两个小时左右才作出来... 所以没提交上也没什么遗憾:)
blueindead 2005-12-13
  • 打赏
  • 举报
回复
做这种题目一般需要两个人。两台电脑。
准备好eclipse,导入util,然后同时开做,我的那道条件排列的题目比较简单,32分钟submit。另外我同学的那道750的也在55分钟的时候submit了。但是这个比赛是按照时间的长短加分的,不知道其他的同学做的怎么样。
rootcn 2005-12-13
  • 打赏
  • 举报
回复
楼主厉害.
我花了很久时间才看明白题意, 分析了一下,代码没写完就到1小时了.

学习一下~~~....
kongfh 2005-12-13
  • 打赏
  • 举报
回复
楼主现在在做什么开发?
5555~~偶这个月加班,没时间报名了。
zez 2005-12-13
  • 打赏
  • 举报
回复
呵呵,我没有重复登录..
第一次登录就特慢,好几分钟后才登录上...
上去后保存,编译..... 几分钟后说 time out.. logoff

这时候我当然要重登录啦..
主要有的时候那个软件自动给代码里不知加了什么 非法字符,编译不过. 我改了再保存,再编译.. 它又说 文件名不对.. 文件名在服务器上, 我这里肯定没有任何办法. 只有重新登录..

反正反反复复,, 一会就到时间了...... 结果就没有 提交成功...
算了...

另外,这道题是这样的:
扑克牌 1-10 , 你可以拿其中任意多张牌(最多 40张牌)
然后出牌,有两种,一种是 同花顺 , 比如 黑桃A,黑桃2,黑桃3... 必须大于等于 3 张
另一种是 刻,也就是打牌的炸和雷, 就是 三张或四张同数的. 比如 三张 3;
然后编程计算你手里的牌,怎么出可以出牌最多,返回出的牌数
zhangts 2005-12-13
  • 打赏
  • 举报
回复
using System;

namespace ConsoleApplication1
{
/// <summary>
/// BusStops 的摘要说明。
/// </summary>
public class BusStops
{
public int countStops(string[] cityMap, int walkingDistance)
{
int row,col=0,i,num=0;
for(i=0;i<cityMap.Length;i++)
if((col=cityMap[i].IndexOf("X"))>-1)
break;
row=i;
for(i=0;i<cityMap.Length;i++)
for(int j=0;j<cityMap[i].Length;j++)
if(cityMap[i][j]=='B' && (Math.Abs(row-i)+Math.Abs(col-j)<=walkingDistance))
num++;
return num;
}
}
}
zhangts 2005-12-13
  • 打赏
  • 举报
回复
using System;

namespace ConsoleApplication1
{
/// <summary>
/// ReverseSubstring 的摘要说明。
/// </summary>
public class ReverseSubstring
{
public string findReversed(string input)
{
int i,pos;
for(i=input.Length;i>0;i--)
{
for(pos=0;pos<=input.Length-i;pos++)
{
string str=input.Substring(pos,i);
System.Text.StringBuilder sb=new System.Text.StringBuilder(str,str.Length);
for(int k=0;k<str.Length;k++)
{
sb[k]=str[str.Length-k-1];
}
if(input.IndexOf(sb.ToString())>-1)
return str;
}
}
return input.Substring(0,1);
}
}
}
zhangts 2005-12-13
  • 打赏
  • 举报
回复
using System;

namespace ConsoleApplication1
{
/// <summary>
/// Disk 的摘要说明。
/// </summary>
using System;
using System.Collections;
public class DiskClusters
{

public int minimumFragmentation(string disk, int size)
{
int pos1=disk.IndexOf(".");
if(pos1==-1)
return -1;
int pos2=pos1;
ArrayList arr=new ArrayList();
while(pos1>-1 && pos1<=pos2 && pos2<disk.Length)
{
while(disk.Length>pos2 && disk[pos2]=='.')
pos2++;
int i;
for(i=0;i<arr.Count;i++)
if((pos2-pos1)>int.Parse(arr[i].ToString()))
break;
arr.Insert(i,pos2-pos1);
pos1=disk.IndexOf(".",pos2);
pos2=pos1;
}
int num;
for(num=0;num<arr.Count;num++)
{
size=size-int.Parse(arr[num].ToString());
if(size<=0)
break;
}
if(num==arr.Count)
return -1;
else
return num+1;
}
}

public class PlayCards
{
public int maxCards(string[] cards)
{
int []car=new int[40];
int i;
for(i=0;i<40;i++)
{
car[i]=0;
}
int temp;
for(i=0;i<cards.Length;i++)
{
string str=cards[i].Substring(cards[i].Length-1,1).ToUpper();
switch(str)
{
case "S":
temp=int.Parse(cards[i].Substring(0,cards[i].Length-1));
car[temp-1]=temp;
break;
case "H":
temp=int.Parse(cards[i].Substring(0,cards[i].Length-1));
car[10+temp-1]=temp;
break;
case "D":
temp=int.Parse(cards[i].Substring(0,cards[i].Length-1));
car[20+temp-1]=temp;
break;
case "C":
temp=int.Parse(cards[i].Substring(0,cards[i].Length-1));
car[30+temp-1]=temp;
break;
}
}


int p=getMax(car,0);
return p;
}

public int getMax(int []car,int col)
{
int num1,num2;
num1=getTotal(car);
if(col>9)
return num1;
if(getSameCol(car,col)<3)
{
return getMax(car,col+1);
}

int []car2=(int[])car.Clone();
if(getSameCol(car,col)==3)
{
for(int i=0;i<4;i++)
if(car2[i*10+col]==col+1)
car2[i*10+col]=0;
num2=getMax(car2,col+1)+3;
}
else
{
for(int i=0;i<4;i++)
car2[i*10+col]=0;
num2=4+getMax(car2,col+1);
for(int j=0;j<4;j++)
{
for(int i=0;i<4;i++)
car2[i*10+col]=0;
car2[j*10+col]=col+1;
int tempMax=3+getMax(car2,col+1);
if(tempMax>num2)
num2=tempMax;
}
}

if(num1>num2)
return num1;
return num2;
}

public int getSameCol(int []car,int col)
{
int num=0;
for(int i=0;i<4;i++)
if(car[i*10+col]==col+1)
num++;
return num;
}
public int getTotal(int []car)
{
int count=0,pos1,pos2;
for(int i=0;i<4;i++)
{
pos1=pos2=0;
for(int j=0;j<10;j++)
{
if(car[i*10+j]==0)
{
if(pos2-pos1>2)
count+=pos2-pos1;
pos1=pos2=j+1;
}
else
{
pos2++;
}
}
if(pos2-pos1>2)
count+=pos2-pos1;
}

return count;
}
}
}
blueindead 2005-12-13
  • 打赏
  • 举报
回复
呵呵,你肯定是重复登陆了,topcoder就是为了防止作弊,不是服务器烂。他的官方已经说了。
我在group15,一道条件排列组合,一道grid 的题目。从代码数量上比你这题简单。
bianlw 2005-12-13
  • 打赏
  • 举报
回复
最好能简单的说说这个程序实现什么功能呢?
netboygg 2005-12-13
  • 打赏
  • 举报
回复
学习。。。。
加载更多回复(6)

23,404

社区成员

发帖
与我相关
我的任务
社区描述
Java 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧