Google CodeJam 2014 Round 1C

Problem: https://code.google.com/codejam/contest/3004486/dashboard


Problem A. Part Elf

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read theQuick-Start Guide to get started.
Small input
8 points
Large input
12 points

Problem

Vida says she's part Elf: that at least one of her ancestors was an Elf. But she doesn't know if it was a parent (1 generation ago), a grandparent (2 generations ago), or someone from even more generations ago. Help her out!

Being part Elf works the way you probably expect. People who are Elves, Humans and part-Elves are all created in the same way: two parents get together and have a baby. If one parent is A/B Elf, and the other parent is C/D Elf, then their baby will be(A/B + C/D) / 2 Elf. For example, if someone who is 0/1 Elf and someone who is1/2 Elf have a baby, that baby will be 1/4 Elf.

Vida is certain about one thing: 40 generations ago, she had 240 different ancestors, and each one of them was 1/1 Elf or 0/1 Elf.

Vida says she's P/Q Elf. Tell her what is the minimum number of generations ago that there could have been a 1/1 Elf in her family. If it is not possible for her to be P/Q Elf, tell her that she must be wrong!

Input

The first line of the input gives the number of test cases, TT lines follow. Each contains a fraction of the form P/Q, where P and Q are integers.

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 minimum number of generations ago a 1/1 Elf in her family could have been if she is P/Q Elf. If it's impossible that Vida could be P/Q Elf, y should be the string "impossible" (without the quotes).

Limits

1 ≤ T ≤ 100.

Small dataset

1 ≤ P < Q ≤ 1000.
P and Q have no common factors. That means P/Q is a fraction in lowest terms.

Large dataset

1 ≤ P < Q ≤ 1012.
P and Q may have common factors. P/Q is not guaranteed to be a fraction in lowest terms.

Sample


Input 
 

Output 
 
5
1/2
3/4
1/4
2/23
123/31488

Case #1: 1
Case #2: 1
Case #3: 2
Case #4: impossible
Case #5: 8

Note that the fifth sample case does not meet the limits for the Small input. Even if you don't solve it correctly, you might still have solved the Small input correctly.

Explanation of sample cases

In the first sample case, Vida could have a 1/1 Elf parent and a 0/1 Elf parent. That means she could have had a 1/1 Elf one generation ago, so the answer is 1.

In the second sample case, Vida could have had a 1/1 Elf parent and a 1/2 Elf parent. That means she could have had a 1/1 Elf one generation ago, so the answer is 1.

In the third sample case, Vida could have had a 0/1 Elf parent and a 1/2 Elf parent. The1/2 Elf parent could have had a 1/1 Elf parent and a 0/1 Elf parent. That means she could have had a 1/1 Elf two generations ago, so the answer is 2.

In the fourth sample case, it's impossible to be exactly 2/23 Elf if your ancestors 40 generations ago were all 0/1 Elf or 1/1 Elf.

Note

Yes, Vida has a lot of ancestors. If that is the part of the problem that seems the most unrealistic to you, please re-read the part about Elves.

#include <cstdio>

long long gcd(long long a, long long b) {
	if (a == 0) return b;
	return gcd(b % a, a);
}

int main() {
	int T;
	scanf("%d", &T);
	for (int ca = 1; ca <= T; ++ca) {
		printf("Case #%d: ", ca);
		long long p, q;
		scanf("%lld/%lld", &p, &q);
		long long d = gcd(p, q);
		p /= d;
		q /= d;
		long long t = q;
		while (t % 2 == 0)
			t /= 2;
		if (t > 1) {
			puts("impossible");
			continue;
		}
		t = 0;
		while (p < q) {
			p *= 2;
			++t;
		}
		printf("%lld\n", t);
	}
	return 0;
}







Problem B. Reordering Train Cars

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read theQuick-Start Guide to get started.
Small input
10 points
Large input
25 points

Problem

Yahya is a brilliant kid, so his mind raises a lot of interesting questions when he plays with his toys. Today's problem came about when his father brought him a set of train cars, where each car has a lowercase letter written on one side of the car.

When he first saw the gift, he was happy and started playing with them, connecting cars together without any particular goal. But after a while he got bored (as usual) from playing without having any goal. So, he decided to define a new interesting problem.

The problem is that he currently has N sets of connected cars. He can represent each set of connected cars as a string of lowercase letters. He wants to count the number of ways he can connect all N sets of cars to form one valid train. A train is valid if all occurrences of the same character are adjacent to each other.

The previous figure is one way Yahya could connect the cars "ab", "bc" and "cd" to make a valid train: "ab bc cd". If he had connected them in the order "cd ab bc", that would have been invalid: the "c" characters would not have been adjacent to each other.

You've surely noticed that this is not an easy problem for Yahya to solve, so he needs your help (and he is sure that you will give it!). That's it; go and help Yahya!

Note: letters are written only on one side of the cars, so you can not reverse them. For example, if a car has "ab" written on it, it could not be changed to read "ba".

Input

The first line of the input gives the number of test cases, TT test cases follow. The first line of each test case contains a single integer N, the number of sets of connected cars. The following line contains N strings separated by a single space. Every given string represents a set of connected cars and is composed of lowercase English letters only.

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 ways of obtaining a valid train. As this number may be very big, output the number of ways modulo 1,000,000,007.

Limits

1 ≤ T ≤ 100.
1 ≤ Set of connected Cars' lengths ≤ 100.

Small dataset

1 ≤ N ≤ 10.

Large dataset

1 ≤ N ≤ 100.

Sample


Input 
 

Output 
 
3
3
ab bbbc cd
4
aa aa bc c
2
abc bcd

Case #1: 1
Case #2: 4
Case #3: 0
Sample Explanation

In the first case, there is only one way to form a valid train by joining string "ab" to "bbbc"to "cd" in this order.

While in the second case, there are 4 possible ways to form a valid train. Notice that there are two different sets of connected cars represented by the string "aa", so there are two different ways to order these two strings and to group them to be one set of connected cars "aaaa". Also there is only one way to order set of cars "bc" with "c" in only one way to be "bcc". After that you can order "aaaa" and "bcc" in two different ways. So totally there are 2*2 = 4 ways to form a valid train.

In the third sample case, there is no possible way to form a valid train, as if joined in any of the two ways "abc"+"bcd" or "bcd"+"abc", there will be two letters of "b" and "c" not consecutive.

C++ Solution for small data:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

int main() {
	int T;
	cin >> T;
	for (int ca = 1; ca <= T; ++ca) {
		long long ans = 0;
		int n;
		cin >> n;
		vector<string> a;
		vector<int> idx;
		for (int i = 0; i < n; ++i) {
			string s;
			cin >> s;
			a.push_back(s);
			idx.push_back(i);
		}
		do {
			string s = "";
			for (int i = 0; i < n; ++i) {
				int j = idx[i];
				s = s + a[j];
			}
			int f[26];
			bool flag = true;
			memset(f, -1, sizeof(f));
			for (int i = 0; s[i]; ++i) {
				int t = s[i] - 'a';
				if (f[t] != -1 && f[t] != i - 1) {
					flag = false;
					break;
				}
				f[t] = i;
			}
			if (flag)
				++ans;
		} while (next_permutation(idx.begin(), idx.end()));
		printf("Case #%d: %lld\n", ca, ans % 1000000007);
	}
	return 0;
}







Problem C. Enclosure

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read theQuick-Start Guide to get started.
Small input
15 points
Large input
30 points

Problem

Your task in this problem is to find out the minimum number of stones needed to place on an N-by-M rectangular grid (N horizontal line segments and M vertical line segments) to enclose at least K intersection points. An intersection point is enclosed if either of the following conditions is true:

  1. A stone is placed at the point.
  2. Starting from the point, we cannot trace a path along grid lines to reach an empty point on the grid border through empty intersection points only.

For example, to enclose 8 points on a 4x5 grid, we need at least 6 stones. One of many valid stone layouts is shown below. Enclosed points are marked with an "x".

Input

The first line of the input gives the number of test cases, TT lines follow. Each test case is a line of three integers: N M K.

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 minimum number of stones needed.

Limits

1 ≤ T ≤ 100.
1 ≤ N.
1 ≤ M.
1 ≤ K ≤ N × M.

Small dataset

N × M ≤ 20.

Large dataset

N × M ≤ 1000.

Sample


Input 
 

Output 
 
2
4 5 8
3 5 11

Case #1: 6
Case #2: 8

C++ solution for small data:

#include <cstdio>

int b[20][20];

void color(const int x, const int y, const int n, const int m) {
	if (x < 0 || x >= n || y < 0 || y >= m || b[x][y] != 0) return;
	b[x][y] = 2;
	color(x - 1, y, n, m);
	color(x + 1, y, n, m);
	color(x, y - 1, n, m);
	color(x, y + 1, n, m);
}

bool check(const int a[20], const int n, const int m, const int k) {
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j)
			b[i][j] = a[i * m + j];
	}
	for (int i = 0; i < m; ++i) {
		color(0, i, n, m);
		color(n - 1, i, n, m);
	}
	for (int i = 0; i < n; ++i) {
		color(i, 0, n, m);
		color(i, m - 1, n, m);
	}
	int cnt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
			if (b[i][j] == 2)
				++cnt;
	return (n * m - cnt == k);
}

int main() {
	int T;
	scanf("%d", &T);
	for (int ca = 1; ca <= T; ++ca) {
		int n, m, k;
		scanf("%d%d%d", &n, &m, &k);
		int ans = k;
		int tmp = (1 << (n * m));
		while (tmp > 0) {
			--tmp;	
			int cnt = 0, a[20] = {0}, i = 0, t = tmp;
			while (t) {
				if (t & 1) {
					a[i] = 1;
					++cnt;
				}
				t = (t >> 1);
				++i;
			}
			if (cnt < ans && check(a, n, m, k)) ans = cnt;
		}
		printf("Case #%d: %d\n", ca, ans);
	}
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值