試題 算法訓練 石子游戲---藍橋杯

試題 算法訓練 石子游戲

題目描述:

資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
  石子游戲的規則如下:
  地上有n堆石子,每次操作可選取兩堆石子(石子個數分別爲x和y)並將它們合併,操作的得分記爲(x+1)×(y+1),對地上的石子堆進行操作直到只剩下一堆石子時停止遊戲。
  請問在整個遊戲過程中操作的總得分的最大值是多少?
輸入格式
  輸入數據的第一行爲整數n,表示地上的石子堆數;第二行至第n+1行是每堆石子的個數。
輸出格式
  程序輸出一行,爲遊戲總得分的最大值。
樣例輸入
10
5105
19400
27309
19892
27814
25129
19272
12517
25419
4053
樣例輸出
15212676150
數據規模和約定
  1≤n≤1000,1≤一堆中石子數≤50000
  
解題思路:

把這些數據從大到小排序,每次取最大的兩個,即可,不難實現。

注意:

使用long long類型,不然不夠。

下面提供兩種方法實現,時刻的排序。其中第二種使用優先隊列。

第一種AC代碼:

#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int a[1000];
int main()
{
	int n,i;
	cin>>n;
	long long ans=0;
	for(i=0;i<n;i++)
		cin>>a[i];
	long long max1,max2,pos1,pos2;//注意類型 
	int t=1;
	while(t<n)//執行n-1次即可 
	{
		max1=0;
		max2=0;
		for(i=0;i<n;i++)//找到最大的那個數字 
			if(max1<a[i])
			{
				max1=a[i];
				pos1=i;
			}
		a[pos1]=0;//爲了找到第二大的數字,現將第一次找到的索引位置數值爲0 
		for(i=0;i<n;i++)//找到第二大的數字 
			if(max2<a[i])
			{
				max2=a[i];
				pos2=i;
			}
		ans+=(max1+1)*(max2+1);
		a[pos1]+=max1+max2;
		a[pos2]=0;
		t++;
	}
	cout<<ans<<endl;
	return 0;
}

第二種AC代碼:

#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
using namespace std;
int main()
{
	//優先隊列,從大到小排序(最先出來的是最小的) 
	priority_queue<long long,vector<long long>,less<long long> >stones;
	long long x,y,ans=0;
	int n;
	cin>>n;
	long long temp;
	for(int i=0;i<n;i++)
	{
		cin>>temp;
		stones.push(temp);
	}
	while(stones.size()>=2)
	{
		x=stones.top();
		stones.pop();
		y=stones.top();
		stones.pop();
		ans+=(x+1)*(y+1);
		stones.push(x+y);
	}
	cout<<ans<<endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章