PAT甲级1010,1011解题报告

1010 Radix (25 分)

Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is yes, if 6 is a decimal number and 110 is a binary number.

Now for any pair of positive integers N​1​​ and N​2​​, your task is to find the radix of one number while that of the other is given.

Input Specification:

Each input file contains one test case. Each case occupies a line which contains 4 positive integers:


N1 N2 tag radix

Here N1 and N2 each has no more than 10 digits. A digit is less than its radix and is chosen from the set { 0-9, a-z } where 0-9 represent the decimal numbers 0-9, and a-z represent the decimal numbers 10-35. The last number radix is the radix of N1 if tag is 1, or of N2 if tag is 2.

Output Specification:

For each test case, print in one line the radix of the other number so that the equation N1 = N2 is true. If the equation is impossible, print Impossible. If the solution is not unique, output the smallest possible radix.

Sample Input 1:

6 110 1 10

Sample Output 1:

2

Sample Input 2:

1 ab 1 2

Sample Output 2:

Impossible

题目大意:英文渣,忍住右键翻译的冲动真的不容易,看了半天大概知道radix是进制的意思,然后就看懂了,大概意思是,输入两个数,进制未知,然后告诉你其中一个数的进制,问你另一个数应该是什么进制才会让两数相等,如果不存在这种进制,那就输出impossible。

解题思路:其实挺坑的。产生了以下几种思路,渐渐变对。

1.先得到已知进制的数的十进制值,为了防止溢出,用了double。然后确认一个范围,检索出第二个数的进制。范围的下限是第二个数的最大字符代表数字+1,上限就是36.(因为我看题目以为只能是a-z表示35,其实并不是这样。)

2.第一种思路写上去了,18分。居然错那么多个样例,仔细想了想,应该是上限不对,毕竟题目没有明确说只有到z为止。那简单的把上限给改了,改成了目标十进制值+1.

3.又提交了一遍,23分。第一个样例错误,一个样例超时。然后又想了想,上限改了之后,检索范围应该是会变大的。而简单的遍历算法效率是O(n*m),m是第二个数的长度。而且算平方也是极其消耗时间的。所以超时也是有可能的,那要优化一下搜索算法,那肯定简单了,用个二分就行了。

4.用了二分之后又交了一遍,24分。这就很纳闷了。第一个样例显示的还是错误。思路应该是没有打错的,那肯定是有个坑的。这时候想了下double的数据类型真的够吗?然后调试了一下,故意搞了个很大的进制数,果然溢出了。那就要处理这个溢出的问题了,其实很简单,首先目标十进制是不会溢出的,那只要在运算过程中发生了溢出,那这个数肯定就是比目标十进制大,只要把这个数溢出的情况当作比目标十进制大的情况处理一下就好了。

5.按上面交了最后一遍,终于25分。

代码如下。

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<time.h>
#include<math.h>
using namespace std;
int chartoint(char a) {
	if (a >= '0'&&a <= '9')
		return a - '0';
	else
	    return a - 'a' + 10;
}
int getminradix(string a) {
	char min = '0';
	for (int i = 0; i < a.size(); i++) {
		if (a[i] > min) {
			min = a[i];
		}
	}
	return chartoint(min) + 1;
}
int main()
{
	string N1, N2;
	long long int tag;
	long long int radix;
	double goal=0;
	cin >> N1 >> N2 >> tag >> radix;
	bool flag = false;
	int res;
	if (tag == 1) {
		for (int i = 0; i <N1.size(); i++) {
			goal += (chartoint(N1[i]) * pow(radix,N1.size()-i-1));
		}
		long long int low = getminradix(N2);
		long long int high = goal + 1;
		while (low <= high) {
			long long int middle = (low + high) / 2;
			double cur = 0;
			for (int j = 0; j <N2.size(); j++) {
				cur += (chartoint(N2[j]) * pow(middle, N2.size() - j - 1));
			}
			if (cur <= 0 || cur > goal) {
				high = middle - 1;
			}
			else if (cur < goal) {
				low = middle + 1;
			}
			else if (cur == goal) {
				res = middle;
				flag = true;
				break;
			}
		}		
	}
	if (tag == 2) {
		for (int i = 0; i <N2.size(); i++) {
			goal += (chartoint(N2[i]) * pow(radix, N2.size() - i - 1));
		}
		long long int low = getminradix(N1);
		long long int high = goal + 1;
		while (low <= high) {
			long long int middle = (low + high) / 2;
			double cur = 0;
			for (int j = 0; j <N1.size(); j++) {
				cur += (chartoint(N1[j]) * pow(middle, N1.size() - j - 1));
			}
			if (cur <= 0 || cur > goal) {
				high = middle - 1;
			}
			else if (cur < goal) {
				low = middle + 1;
			}
			else if (cur == goal) {
				res = middle;
				flag = true;
				break;
			}
		}
	}
	if (!flag) {
		cout << "Impossible" << endl;
	}
	else {
		cout << res << endl;
	}
	return 0;
}

1011

1011 World Cup Betting (20 分)

With the 2010 FIFA World Cup running, football fans the world over were becoming increasingly excited as the best players from the best teams doing battles for the World Cup trophy in South Africa. Similarly, football betting fans were putting their money where their mouths were, by laying all manner of World Cup bets.

Chinese Football Lottery provided a "Triple Winning" game. The rule of winning was simple: first select any three of the games. Then for each selected game, bet on one of the three possible results -- namely W for win, T for tie, and L for lose. There was an odd assigned to each result. The winner's odd would be the product of the three odds times 65%.

For example, 3 games' odds are given as the following:

 W    T    L
1.1  2.5  1.7
1.2  3.1  1.6
4.1  1.2  1.1

To obtain the maximum profit, one must buy W for the 3rd game, T for the 2nd game, and T for the 1st game. If each bet takes 2 yuans, then the maximum profit would be (4.1×3.1×2.5×65%−1)×2=39.31 yuans (accurate up to 2 decimal places).

Input Specification:

Each input file contains one test case. Each case contains the betting information of 3 games. Each game occupies a line with three distinct odds corresponding to WT and L.

Output Specification:

For each test case, print in one line the best bet of each game, and the maximum profit accurate up to 2 decimal places. The characters and the number must be separated by one space.

Sample Input:

1.1 2.5 1.7
1.2 3.1 1.6
4.1 1.2 1.1

Sample Output:

T T W 39.31

题目大意:大概意思就是赌球。三场比赛赔率告诉你,每场两块钱,问你怎么压才能让理论上收益最大化。

解题思路:水的不行,读三次三个数,把每次最大的数标记一下,最后计算输出一下。

代码如下

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<time.h>
#include<math.h>
using namespace std;
int main()
{
	double a, b, c;
	double res = 1;
	char ress[5];
	for (int i = 0; i < 3; i++) {
		cin >> a >> b >> c;
		res *= max(a, max(b, c));
		if (a == max(a, max(b, c))) {
			ress[i] = 'W';
		}
		else if (b == max(a, max(b, c))) {
			ress[i] = 'T';
		}
		else if (c == max(a, max(b, c))) {
			ress[i] = 'L';
		}
	}
	for (int i = 0; i < 3; i++)cout << ress[i] << " ";
	printf("%.2lf\n", (res*0.65 - 1) * 2);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/TateBrwonJava/article/details/82937979