洛谷 p1080 國王遊戲 高精度問題

先上代碼!

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
FILE* stream;


struct p
{
	int l;
	int r;
	int l_r;
}ps[1000000];

bool cmp(p c1, p c2) {//用於sort函數的排序;
	return c1.l_r < c2.l_r;
}

bool compare(string s1,string s2) {
	if (s1.size() > s2.size()) {
		return true;
	}
	else if (s1.size()==s2.size()) {
		if (s1.compare(s2) > 0) {
			return true;
		}
		else
		{
			return false;
		}
	}
	else {
		return false;
	}
}

string mul_1(string s1, int x) {//高精度乘以低精度
	int a[5000], c[5000];//由於最多隻有1000個大臣,而且每個人的左手上的數字最多四位,所以最大4000位,定個5000
	memset(a, 0, 5000 * sizeof(int));
	memset(c, 0, 5000 * sizeof(int));
	int l_1 = s1.size();//各自的長度
	int l_3 ;
	for (int i = 0; i < l_1; i++)//按位拆分再存進數組裏,地位存放數字低位
	{
		a[i] = s1[l_1 - i - 1] - '0';
	}
	for (int i = 0; i < l_1; i++)//先按位相乘,然後進位,然後取模,這裏可能會導致,有部分未進位部分留在c[l_1]
	{
		c[i] += x * a[i];
		c[i + 1] = c[i] / 10;
		c[i] = c[i] % 10;
	}
	int i = l_1;
	while(c[i]>10){
		c[i + 1] = c[i]/10;
		c[i] = c[i] % 10;
		i++;
	}
	if (c[i] > 0) {
		l_3 = i;
	}
	else {
		l_3 = i - 1;
	}
	string ans;
	for (int i = l_3; i >= 0; i--)
	{
		
		ans += (c[i] + '0');
	}
	return ans;
}

string mul(string s1,string s2) {//高精度乘以高精度
	int a[5000], b[5000], c[5000];
	memset(a, 0, 5000 * sizeof(int));
	memset(b, 0, 5000 * sizeof(int));
	memset(c, 0, 5000 * sizeof(int));
	int l_1 = s1.size();
	int l_2 = s2.size();
	int l_3;
	for (int i = 0; i < l_1; i++)//按位拆分再存進數組裏,地位存放數字低位
	{
		a[i] = s1[l_1 - i - 1]-'0';
	}
	for (int i = 0; i < l_2; i++)
	{
		b[i] = s2[l_2 - i - 1]-'0';
	}
	for (int i = 0; i < l_2; i++)//b
	{
		
		for (int j = 0; j < l_1; j++)//a
		{
			c[i + j] += a[j] * b[i];
		}
	}
	int temp = 0;
	for (int i = 0; i < l_1+l_2; i++)
	{
		temp = c[i] / 10;
		c[i] = c[i] % 10;
		c[i + 1] += temp;
	}
	bool flag = true;
	string ans="";
	for (int i = l_1+l_2-1; i >= 0; i--)
	{
		if (c[i] != 0&&flag) {//抓住第一個非0數字
			flag = false;
			ans += c[i] + '0';
			continue;
		}
		if (!flag) {
			ans += c[i] + '0';
		}
	}
	return ans;
}

string div_1(string s1, int x) {//高精度除以低精度
	int a[5000], c[5000];
	memset(a, 0, 5000 * sizeof(int));
	memset(c, 0, 5000 * sizeof(int));
	int l_1 = s1.size();
	int l_3;
	for (int i = 0; i < l_1; i++)//按位拆分再存進數組裏,地位存放數字低位
	{
		a[i] = s1[l_1 - i - 1] - '0';
	}
	int temp=0;
	bool flag = true;
	for (int i = l_1-1; i >=0 ; i--)
	{
		temp = temp * 10 + a[i];
		c[i] = temp / x;
		temp = temp % x;
		if (flag && c[i] != 0) {
			l_3 = i;
			flag = false;
		}
	}
	if (flag) {
		return "0";
	}
	string ans;
	for (int i = l_3; i >= 0; i--)
	{
		ans += (c[i] + '0');
	}
	return ans;

}

int main() {
	/*stream = freopen("1.in", "r", stdin);
	if (stream == NULL) {
		return 0;
	}*/
	int n;
	cin >> n;
	n++;
	int temp1, temp2;
	for (int i = 0; i < n; i++)
	{
		cin >> temp1 >> temp2;
		ps[i].l = temp1;
		ps[i].r = temp2;
		ps[i].l_r = temp1 * temp2;
	}
	//cout << "hi" << endl;
	sort(ps+1, ps + n, cmp);
	int ans = 0;
	string Bignum="1";
	string coin;
	string max="0";
	for (int i = 1; i < n; i++)
	{
		Bignum = mul_1(Bignum, ps[i-1].l);
		coin = div_1(Bignum, ps[i].r);
		if (compare(coin, max)) {
			max = coin;
		}
	}
	cout << max;

	return 0;
}

問題的難度主要集中在高精度數字的計算上。

學習出處!https://www.codercto.com/a/18273.html   and   https://www.luogu.com.cn/problemnew/solution/P1080

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章