CodeJam Kickstart 初见

之前也在尝试参加CodeJam的Contest,跟LC不太一样,输入输出是文件形式,

看似没有时间限制,其实是有的


Problem

Alice likes reading and buys a lot of books. She stores her books in two boxes; each box is labeled with a pattern that matches the titles of all of the books stored in that box. A pattern consists of only uppercase/lowercase English alphabet letters and stars (*). A star can match between zero and four letters. For example, books with the titlesGoneGirl and GoneTomorrow can be put in a box with the pattern Gone**, but books with the titles TheGoneGirl, and GoneWithTheWind cannot.

Alice is wondering whether there is any book that could be stored in either of the boxes. That is, she wonders if there is a title that matches both boxes' patterns.

Input

The first line of the input gives the number of test cases, TT test cases follow. Each consists of two lines; each line has one string in which each character is either an uppercase/lowercase English letter or *.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is TRUE if there is a string that matches both patterns, orFALSE if not.

Limits

1 ≤ T ≤ 50.

Small dataset

1 ≤ the length of each pattern ≤ 200.
Each pattern contains at most 5 stars.

Large dataset

1 ≤ the length of each pattern ≤ 2000.

Sample


Input 
 

Output 
 
3
****
It
Shakes*e
S*speare
Shakes*e
*peare

Case #1: TRUE
Case #2: TRUE
Case #3: FALSE


In sample case #1, the title It matches both patterns. Note that it is possible for a * to match zero characters.

In sample case #2, the title Shakespeare matches both patterns.

In sample case #3, there is no title that matches both patterns. Shakespeare, for example, does not work because the * at the start of the *peare pattern cannot match six letters.



最开始想着用递归,先写出的版本有bug,跑得挺快的,但是有bug

package PatternsOverlap;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;
import java.util.Scanner;

/*
 * 2个字符串都可能有*
 * 如果这个字符串最开始都是*,那可以去掉其中一个,因为两个*取同样的字符是浪费
 *
 * bug: 考虑 * 与 aa*bb
 * fix:
 */
public class bug {
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(new BufferedReader(new FileReader("a2.in")));
		PrintStream ps=new PrintStream(new FileOutputStream("a2.out"));
		System.setOut(ps);
		
		int cnt = sc.nextInt();
		for(int cc=1; cc<=cnt; cc++) {
			String s = sc.next(), t = sc.next();
			boolean f = ok(s, t);
			if(f)
				System.out.println("Case #" + cc + ": TRUE");
			else
				System.out.println("Case #" + cc + ": FALSE");
		}
		
	}

	public static boolean ok(String s, String t) {
		if("".equals(s) && "".equals(t))	return true;
		if("".equals(s))	return t.replace("*", "").equals("");
		if("".equals(t))	return s.replace("*", "").equals("");
		
		if(s.charAt(0)=='*' && t.charAt(0)=='*') 
			return ok(s.substring(1), t) || ok(s, t.substring(1));
		
		if(s.charAt(0)=='*') {
			for(int i=0; i<=Math.min(t.length(), 4); i++)
				if(ok(s.substring(1), t.substring(i)))
					return true;
			return false;
		}
		
		if(t.charAt(0)=='*') {
			for(int i=0; i<=Math.min(s.length(), 4); i++)
				if(ok(t.substring(1), s.substring(i)))
					return true;
			return false;
		}
		
		return s.charAt(0)==t.charAt(0) && ok(s.substring(1), t.substring(1));
	}
}

那就改吧,把*全部换成????,然后?可以匹配一个或者0个字符,然后按照这种匹配的规则写递归就好了,最好是分成若干中情况讨论

但是写完好像是进入死循环了,其实是长度变为原来的4倍,而复杂度又是指数级别的,时间暴增。那记忆化搜索把

package PatternsOverlap;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/*
 * 2个字符串都可能有*
 * 如果这个字符串最开始都是*,那可以去掉其中一个,因为两个*取同样的字符是浪费
 *
 * bug: 考虑 * 与 aa*bb
 * fix: 把*全部换成4个?,那?就是必须匹配上
 * 
 * 死循环。。。。好多重复的计算,但是为什么之前的递归没有死循环????
 * (长度是原来的4倍,但是复杂度是指数增长!!)
 */
public class Main {
	
	static Map<String, Boolean> m = new HashMap<String, Boolean>();
	
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(new BufferedReader(new FileReader("b.in")));
		PrintStream ps=new PrintStream(new FileOutputStream("a.out"));
		System.setOut(ps);
		
		int cnt = sc.nextInt();
		for(int cc=1; cc<=cnt; cc++) {
			String s = sc.next(), t = sc.next();
			boolean f = ok(s.replace("*", "????"), t.replace("*", "????"));
			if(f)
				System.out.println("Case #" + cc + ": TRUE");
			else
				System.out.println("Case #" + cc + ": FALSE");
		}
		
	}

	public static boolean ok(String s, String t) {
		if("".equals(s) && "".equals(t))	return true;
		if("".equals(s))	return t.replace("?", "").equals("");
		if("".equals(t))	return s.replace("?", "").equals("");
		if(m.containsKey(s+" "+t))	return m.get(s+" "+t);
		
		boolean f = false;
		
		
		/*
		 * 就是按照思路来递归啊
		 * ?可以匹配一个字符,也可以不匹配字符
		 */ 
		if(s.charAt(0)=='?' && t.charAt(0)=='?') 
			f =  ok(s.substring(1), t) || ok(s, t.substring(1));
		else if(s.charAt(0)=='?')
			f = ok(s.substring(1), t) || ok(s.substring(1), t.substring(1));
		else if(t.charAt(0)=='?') 
			f = ok(s, t.substring(1)) || ok(s.substring(1), t.substring(1));
		else
			f = s.charAt(0)==t.charAt(0) && ok(s.substring(1), t.substring(1));
		
		m.put(s+" "+t, f);
		return f;
	}
}

小的测试用例上跑得还挺快的,但是用大测试用例就StackOverflowError了,看来只能是优化为DP版本了(略)




另外附上另外一个宣讲会上别人举为例子的题,说是要开动思维

Problem

Mr. Panda has recently fallen in love with a new game called Square Off, in which players compete to find as many different squares as possible on an evenly spaced rectangular grid of dots. To find a square, a player must identify four dots that form the vertices of a square. Each side of the square must have the same length, of course, but it does not matter what that length is, and the square does not necessarily need to be aligned with the axes of the grid. The player earns one point for every different square found in this way. Two squares are different if and only if their sets of four dots are different.

Mr. Panda has just been given a grid with R rows and C columns of dots. How many different squares can he find in this grid? Since the number might be very large, please output the answer modulo 109 + 7 (1000000007).

Input

The first line of the input gives the number of test cases, TT lines follow. Each line has two integers R and C: the number of dots in each row and column of the grid, respectively.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the number of different squares can be found in the grid.

Limits

1 ≤ T ≤ 100.

Small dataset

2 ≤ R ≤ 1000.
2 ≤ C ≤ 1000.

Large dataset

2 ≤ R ≤ 109.
2 ≤ C ≤ 109.

Sample


Input 
 

Output 
 
4
2 4
3 4
4 4
1000 500

Case #1: 3
Case #2: 10
Case #3: 20
Case #4: 624937395

The pictures below illustrate the grids from the three sample cases and a valid square in the third sample case.







package SquareCounting;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;
import java.util.Scanner;

/*
 * 先计算可能的边长
 * 对每个边长求出包围它的最小正方形
 * 求出原矩形包含多少个这样的正方形
 */
public class Main {
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(new BufferedReader(new FileReader("a.in")));
		PrintStream ps=new PrintStream(new FileOutputStream("a.out"));
		System.setOut(ps);
		
		int cnt = sc.nextInt();
		for(int cc=1; cc<=cnt; cc++) {
			int n=sc.nextInt()-1,m =sc.nextInt()-1;
			int min = Math.min(n, m);
			
			long ret = 0;
			for(int i=0; i<=min; i++) {
				for(int j=i; j<=min; j++) {
					if(i+j == 0)	continue;
					if(i+j > min)	break;
					long repate = (n-(i+j)+1)*(m-(i+j)+1) % 1000000007;
					
					if(i == j || i==0 || j== 0)	ret += repate;
					else	ret += 2*repate;
					
					ret %= 1000000007;
				}
			}
			
			System.out.println("Case #" + cc + ": " + ret);
		}
		
	}
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值