1. 程式人生 > 其它 >廣西大學“中國東信杯”第三屆程式設計競賽-新生組-部分題解

廣西大學“中國東信杯”第三屆程式設計競賽-新生組-部分題解

技術標籤:題解c++博弈論dfs模擬

一、A+++++++++++

題目描述:

有一天,小西的好朋友Antinomy來到西大參觀,發現校園裡有兩副巨大的畫,一幅的標題是《創新》,一幅的標題是《創業》,但都是空白的。於是Antinomy問小西:“這兩幅畫應該是畫的什麼呀?”小西:“裡面是正在從事創新或者創業的同學。”Antinomy:“什麼是創新?”小西:“從事高水平科研技術研究和參加高水平學科競賽,簡單來說就是學術活動和技能訓練。”Antinomy:“什麼是創業?”小西:“基於行業實際發展情況和實時政治經濟情況,在有限資本下創立可持續盈利且具有較大發展空間的活動。”小西:“至於為什麼這兩幅畫是空白的,因為同學們都在參加創新創業競賽。”

眾所周知,創新創業類競賽是我們學校人均參加的重量級競賽,這一類別的競賽在評獎評優或推免評比的考核中佔據絕對性優勢,即所謂的“A+”類競賽。
但眾所周知,之所以A+類競賽是A+類競賽,只是因為最高只能是這麼多,現在Antinomy想知道,假設沒有這個限制,給出競賽名稱冠名的Title集合,請求出這個競賽的等級。
小西認為,對於給出的nnn個title中,每能組成一對<national,nternational><national,international><national,international>(也就是中國國際),那麼競賽的等級就可以在A的基礎上增加一個+。

輸入描述

輸入第一行為測試用例T,接下來有T組測試資料每組測試用例第一行為一個整數n,表示有n個title,接下來n行每行一個字串表示第i個title,title只可能是national或者international
1≤T≤100
3≤n≤10^4

輸出描述

對於每組測試用例輸出此時的競賽等級

示例
輸入

4
3
national
international
national
4
national
international
national
international
4
national
national
national
national
4
international
international

national
national

輸出

A+
A++
A
A++

這題就是簡單的統計national和international的數量,取兩者最小值,即兩者最多能組成多少對。

#include<iostream>
#include<string>
using namespace std;
int main ()
{
	int t;
	cin >> t;
	while ( t-- )
	{
		int n, book[2] = { 0 };
		cin >> n;
		while ( n-- )
		{
			string arr;
			cin >> arr;
			if ( arr == "national" )
				book[0]++;
			if ( arr == "international" )
				book[1]++;
		}
		cout << "A";
		for ( int i = 1; i <= min ( book[0], book[1] ); i++ )
			cout << "+";
		cout << endl;
	}

	return 0;
}

二、GDP Carry

題目描述

小西和Antinomy又來到君武樓,這裡正在做A+類競賽校賽的答辯,他們偷偷翻了翻參加答辯的專案組的專案計劃書,發現每個計劃書都有日流水這樣的指標,他們決定做一個遊戲。現在有nnn個專案計劃書,每個計劃書上有一個日流水數字,將這nnn個日流水視為一個長度為nnn的序列fff,兩人輪流操作,Antinomy先手,Antinomy每次需要把fff中非空的連續的一段移除,要求這一段的元素和需要為奇數;小西也每次需要把F中非空的連續的一段移除,但是這一段的元素和需要為偶數,如果輪到誰的時候無法操作下去那麼這個人就判定為輸。移除一段之後,原來這一段之前的部分和原來這一段之後的部分也視為連續。已知他們都會採取最優的策略,給出這nnn個日流水,請問最後誰會贏呢?

輸入描述

第一行輸入nnn,表示fff的長度,接下來一行nnn個整數分別表示f0,f1·······fn-1
3<=n<=10^6
1<=fi<=10^9

輸出描述

輸出一行一個字串表示勝利者,如果Antinomy勝利那麼輸出Antinomy,否則輸出XiJam

示例1
輸入

4
1 2 3 4

輸出

Antinomy

示例2
輸入

3
2 2 4

輸出

XiJam

這道題是一個簡單的博弈論問題,因為是Antinomy(龍大佬)先手,且只能拿奇數,所以

如果流水和為奇數,那麼龍老闆可以直接全部拿走,龍老闆勝,輸出Antinomy
如果流水和為偶數
1.每份流水都是偶數,不管怎麼組合,偶數+偶數只能是偶數,所以龍老闆必輸,輸出XiJam
2.有部分流水是奇數,龍老闆先手拿走奇數,那麼總數=偶數-奇數=奇數,所以Xijam第二手不可能直接全部拿走,只能拿走一個偶數,那麼!!奇數-偶數==奇數,所以第三手,龍老闆又可以直接全部拿走。

綜上分析:只有全部都是偶數,龍老闆才能輸!

#include<iostream>
using namespace std;
int main ()
{
	int book=0,n;
	cin >> n;
	long long temp;
	for ( int i = 1; i <= n; i++ )
	{
		cin >> temp;
		if ( temp % 2 != 0 )
			book = 1;
	}
	if ( book == 1 )
		cout << "Antinomy" << endl;
	else cout << "XiJam" << endl;
	return 0;
}

三、Interpretability

小西和Antinomy在翻A+級比賽答辯的PPT時,發現PPT裡列舉的諸多指標之間都有相互支撐的關係,他們共同組織成了讓評委看起來覺得很厲害同時也能站得住腳的觀感。說到站得住腳,眾所周知三角形具有良好的穩定性,小西和Antinomy還發現,這一堆PPT列出的指標裡,每個指標都有一個可信度。如果任意三個指標的可信度,將其視為長度時能組成一個三角形的話,那麼這三個指標就能相互支撐,從而看起來站得住腳。經過整理之後發現,每個指標的可信度都是2的正整數次冪,且可信度為2^i的指標有fi個,只考慮三個指標相互支撐的情況,每個指標只能被用在一個相互支撐的三角形裡。現在Antinomy和小西想知道,給定一個數字n,以及n個數字f1,f2,…fnf_1,f_2,…f_nf1​,f2​,…fn​,這些指標最多能形成多少個相互支撐的三角形體系?

輸入描述

輸入描述輸出描述

輸出一行一個整數表示最多能形成多少個三角形體系。

示例1
輸入

3
1 1 1

輸出

0

示例2
輸入

5
1 2 2 2 2

輸出

3

示例3
輸入

3
3 3 3

輸出

3

提示

提示:並不是非要把2i2^i2i存下來

首先,根據兩邊之和大於第三邊,我們可以得到,這些值裡,任意不相等的三個是不可能組成一個三角形,所以只有等腰或者等邊可以考慮。
為什麼優先等腰,因為要保證最多,就要儘量用之前的“多餘的邊角料”!

#include<iostream>
using namespace std;
int main ()
{
	long long n, f,book=0,ans=0;
	cin >> n;
	while ( n-- )
	{
		cin >> f;
		
		while( f>=2 && book > 0 )//優先等腰
		{
			ans++;
			f -= 2;
			book--;
		}
		ans += f / 3;//然後等邊
		book += f % 3;
	}
	cout << ans << endl;
	return 0;
}

四、Normalization

本人水平不夠,過!

五、小西和數字轉換

本人太懶了。。直接連結看題吧
密碼:2020gxuacm19
小西和數字轉換

這個題,,需要你理解取餘的過程,比如n%100,百位以及以上的數字是多少,都不會影響取餘的結果,所以只需要考慮百位以下的位置
本體原理相同

#include<iostream>
#include<string>
using namespace std;
int main ()
{
	string num;
	int n,x,y;
	cin >> n >> x >> y;
	cin >> num;
	int ans = 0;
	for ( int i = n - x ; i < n; i++ )
	{
		if ( ( num[i] == '1' && i != n - y - 1 ) || ( num[i] == '0' && i == n - y - 1 ) )
			ans++;
	}
	cout << ans << endl;
	return 0;
}

六、小西和拼圖

小西和拼圖
密碼:2020gxuacm19

首先要明白主對角線的概念(這邊建議百度)


主對角線明白了這題就比較簡單了,只需要有左下跟右上相等的矩形,那麼就可以拼出這個題目要求

#include<iostream>
using namespace std;

int temp[2][2];
int main ()
{
	int t;
	cin >> t;
	while ( t-- )
	{
		int n, m;
		cin >> n >> m;
		int book = 0;
		for ( int i = 1; i <= n; i++ )
		{
			cin >> temp[0][0] >> temp[0][1] >> temp[1][0] >> temp[1][1];
			if ( temp[1][0] == temp[0][1] )
				book = 1;
		}
		if ( m % 2 == 0 && book == 1 )
			cout << "YES" << endl;
		else cout << "NO" << endl;
	}
return 0;
}

七、小西和複製貼上

小西和複製貼上
密碼:2020gxuacm19
這個題思路比較複雜,逆序推導,此處參考了一下lmgg的程式碼,自己理解吧

#include<iostream>
#include<string>
#define MAX 200005
using namespace std;
int a[MAX], b[MAX], c[MAX];
int main ()
{
	long long k, m, n;
	string arr;
	cin >> k >> m;
	cin >> arr;
	cin >> n;
	for ( int i = 0; i < n; i++ )
		cin >> a[i] >> b[i] >> c[i];

	for ( int i = 0; i < k; i++ )
	{
		int p = i;
		for ( int j = n - 1; j >= 0; j-- )
		{
			if ( c[j] <= p )
			{
				if ( c[j] + b[j] - a[j] <= p )
				{
					p -= b[j] - a[j];
				}
				else//超過m裁掉那種
				{
					p = a[j] + p - c[j];
				}
			}

		}
		cout << arr[p];

	}
	cout << endl;
	return 0;
}

最後把我爆記憶體的程式碼貼出來給大家欣賞 以此為戒

#include<iostream>
#include<string>
using namespace std;
int main ()
{
	string arr;
	long long k, m, n;
	cin >> k >> m;
	cin >> arr;
	cin >> n;
	while ( n-- )
	{
        string book;
		long long a, b, c;
		cin >> a >> b >> c;
		book = arr.substr ( a, b-a );
		arr.insert ( c, book );
		string Arr = arr.substr ( 0, m );
		arr = Arr;
	}
	for ( int i = 0; i < k; i++ )
		cout << arr[i];
	cout << endl;
	return 0;
}

這次競賽,除了第四個有點點複雜的模擬,和第七個思路比較複雜,第八個dfs需要一定的基礎,其餘五題作為一個新生做出來應該問題不大。