POJ2000 Gold Coins
- 题目:Gold Coins
- 题解:如果只开一个数组存每天获得的金币的话,一共要存(10000*10001)/2这么多的数,显然不太理想,可以转化为一共10000轮,每轮送N天每天N个,保存每轮的终点,另开一个数组保存从开始到该轮结束的金币总数
package 蓝桥;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[] num=new int[10001];//下标表示该轮连送N天每次N个,值表示这一轮最后一天
int[] coin=new int[10001];//每轮送完共送多少个
for(int i=1;i<10001;i++) {
//0 1 3 6 10,即第一轮到第一天每次一个,第二轮到第三天每次两个……
num[i]=i+num[i-1];
//连送i天每次i个加上上一轮送的
coin[i]=i*i+coin[i-1];
}
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
int n=sc.nextInt();
if(n==0) return;
for(int i=1;i<10001;i++) {
if(n<=num[i]) {//在这一轮内
int gold=coin[i]-(num[i]-n)*i;//离送完那天差几天就减掉几天的
System.out.println(n+" "+gold);//按格式输出
break;
}
}
}
}
}
POJ2001 Shortest Prefixes
-
题解
2.1:暴力枚举每个单词所有前缀验证可行性
package 蓝桥;
public class Main {
static String[] str=new String[1001];
static String[] pre=new String[1001];
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int i=0;
while(sc.hasNext()) {
str[i]=sc.next();
//自己测试数据结尾要输入Ctrl+Z表示输入结束
i++;
}
for(i=0;str[i]!=null;i++) {//获取每个单词的最短前缀
if(pre[i]==null)
getpre(str[i],i);
}
for(i=0;pre[i]!=null;i++) {//按格式输出
System.out.println(str[i]+" "+pre[i]);
}
}
static void getpre(String s,int n) {
for(int end=1;end<s.length()+1;end++ ) {
String sPre=s.substring(0, end);
//枚举所有前缀
if(cheak(sPre,end,n)) {//可行,求下一个单词
pre[n]=sPre;
return;
}
if(end==s.length()) {//如果除了他本身以外的前缀都不能用,那本身就是最短前缀
pre[n]=sPre;
}
}
}
private static boolean cheak(String sPre, int end,int n) {
for(int i=0;str[i]!=null;i++) {//遍历所有单词
if(i==n) continue;//不求本身
if(end>str[i].length()) {//该单词长度比所求前缀短,目前可行,求下一单词
continue;
}
if(sPre.equals(str[i])) {
//该单词和该前缀完全相同,则该单词的前缀就是他本身,且该前缀不可行
pre[i]=str[i];
return false;
}
String s=str[i].substring(0, end);
if(sPre.equals(s)) {//该单词有相同的前缀,不可行
return false;
}
}
return true;
}
}
2.2:字典树
package 蓝桥;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Trie trie = new Trie();
Queue<String> queue = new LinkedList<String>();
while (sc.hasNext()) {
String word = sc.nextLine();
queue.offer(word);
trie.insert(word);
}
while (!queue.isEmpty()) {
String word = queue.poll();
System.out.println(word + " " + trie.search(word));
}
sc.close();
}
}
class Trie {
private Node root;
public Trie() {
root = new Node(new Node[26], 0);
}
public void insert(String word) {
Node current = root;
for (int i = 0; i < word.length(); ++i) {
if (null != current.getSon(word.charAt(i) - 'a')) {
current = current.getSon(word.charAt(i) - 'a');
current.setCount(current.getCount() + 1);
} else {
Node newNode = new Node(new Node[26], 1);
current.setSon(word.charAt(i) - 'a', newNode);
current = newNode;
}
}
}
public String search(String word) {
Node current = root;
StringBuilder prefix = new StringBuilder();
for (int i = 0; i < word.length(); ++i) {
if (1 == current.getCount()) {
break;
}
prefix.append(word.charAt(i));
current = current.getSon(word.charAt(i) - 'a');
}
if (1 == current.getCount()) {
return prefix.toString();
} else {
return word;
}
}
}
class Node {
private Node[] son;
private int count;
public Node(Node[] son, int count) {
this.son = son;
this.count = count;
}
public Node getSon(int i) {
return son[i];
}
public void setSon(int i, Node node) {
son[i] = node;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
POJ2005 Blackjack
- 题目:Blackjack
- 题解:因为A的大小由执牌者决定,而除非两张A不然不会爆点,所以A总是11.
package 蓝桥;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String[] card; // 存储输入数据
int[] poker;//手牌
int[] num;//每张牌出现次数
int player, dealer;//玩家手牌的点数,庄家手牌点数
double count;//现有牌数
int sum;//玩家能赢的所有情况
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
if (n == 0)
return;
card = new String[3];
num = new int[14];
poker = new int[3];
for (int i = 0; i < 3; i++) {
card[i] = sc.next();
poker[i] = change(card[i]);
num[poker[i]]++;
}
count = n * 52 - 3;
player = poker[1] + poker[2];
if (player == 22) {
player = 12;
}
dealer = poker[0];
sum = 0;
for (int i = 2; i <= 11; i++) {
if (((dealer + i == 22) ? 12 : dealer + i) < player) {
if (i == 10)
sum += n * 4 * 4 - num[i]; //TJQK 四个10。
else
sum += n * 4 - num[i]; // 如果出现过,就要减去
}
}
System.out.printf("%.3f%%\n\n", sum * 100 / count);//注意输出格式
}
}
static int change(String num) {
char ch = num.charAt(0);
if (ch == 'A')
return 11;
else if (ch == 'T' || ch == 'J' || ch == 'Q' || ch == 'K')
return 10;
else
return ch - '0';
}
}