Educational Codeforces Round 107 (Rated for Div. 2)題解


題目鏈接

被B題卡到了,唉,還是自己人傻逼。

A題

題意:有三種類型的客人,他們依次到來,一種反對者,一種支持者,還一種觀望者,即根據當前情況,如果反對數 > 支持數,就投反對,反之投支持的人,現在你有兩個投票系統,你可以選擇給當前來到的客人展示其中一種,問你最多可以獲得多少票支持。

思路:顯然就是支持者數目 + 觀望者數目, 因為顯然我們可以讓反對只投到一個投票系統上。

int main()
{
	IOS;
	int T;
	cin >> T;
	while(T --)
	{
		int n;
		cin >> n;
		int up = 0, down = 0;
		for(int i = 0 ; i < n ; i ++)
		{
			int r;
			cin >> r;
			if(r == 1) up ++;
			else if(r == 2) down ++;
			else	up ++;
		}
		cout << up << "\n";
	}
	return 0;
}

B題

題意:給三個數\(a, b, c\), 讓你找到兩個數\(x\)\(y\),使得\(x,y,gcd(x, y)\)這三個數的位數分別是\(a,b,c\)

思路:顯然是一個構造題,想辦法構造即可。
我開始沒寫程序檢驗,想當然以為是對了,卡了半天,還wa了4發,心疼。
我構造的是往數的末尾添3和7的方法,但是注意\(gcd(1003, 17) = 17\)這個唯一的坑爹情況(下面的三目運算用途正是如此),由於數據范圍不大,這種可以自己打表檢驗規避!!!
代碼如下

int base[11];
 
int main()
{
	IOS;
	int T;
	cin >> T;
	base[1] = 0;
	int t = 1;
	for(int i = 2 ; i <= 10 ; i ++)
		t = t * 10, base[i] = t;
	while(T --)
	{
		int a, b, c;
		cin >> a >> b >> c;
		int x;
		if(a == 1) x = 1;
		else x = (base[a - c + 1] + (a >= b ? 7 : 3)) * (base[c] ? base[c] : 1);
		
		int y;
		if(b == 1) y = 1;
		else y = (base[b - c + 1] + (b > a ? 7 : 3)) * (base[c] ? base[c] : 1);
		cout << x << " " << y << endl;
	}
	return 0;
}

C題

題意:從前往后給你n張卡片,每個卡片都有一個顏色,然后有m次詢問,每次詢問找到最前面的這個顏色的卡片,輸出它的下標,然后把它放到最開頭去。

思路:由於卡片的顏色最多只有50種,顯然我們只需要維護每種顏色最前面的卡片即可,因為后面的沒有意義,我們從前面拿一張放到開頭去,它的下標沒有變化。
代碼如下

int n, q;
int idx[55];
 
 
int main()
{
	IOS;
	cin >> n >> q;
	for(int i = 1 ; i <= n ; i ++)
	{
		int x;
		cin >> x;
		if(!idx[x]) idx[x] = i;
	}
	while(q --)
	{
		int p;
		cin >> p;
		cout << idx[p] << " ";
		for(int i = 1 ; i <= 50 ; i ++)
			if(idx[i] < idx[p])
				idx[i] ++;
		idx[p] = 1;
	}
 
	return 0;
}

D題

題意:讓你用從'a'開始的前k個字母,構造一個字符串S(此處下標從1開始),使得滿足\(1 <= i < j <= len(S),S_i = S_j , S_{i + 1} = S_{j + 1}\)\({i, j}\)對數最少。

思路:我們以雙字符組成的串來看,可以選擇hash把它們映射成\(0到675\)的數,根據上一個字母枚舉當前字母,選擇當前字母能構成的之前出現次數最少的雙字符,每次盡量選擇較后的字母,因為我們是從前往后枚舉的,這樣能最大化預留之后的選擇空間。
代碼如下

int cnt[700];
char s[N];

int main()
{
	IOS;
	int n, k;
	cin >> n >> k;
 
	s[0] = 'a';
	int last = 0;
	for(int i = 1 ; i < n ; i ++)
	{
		int mind = 1e9, d = -1;
		for(int j = 0 ; j < k ; j ++)
		{
			if(mind >= cnt[last * 26 + j])
			{
				mind = cnt[last * 26 + j];
				d = j;
			}		
		}
		cnt[last * 26 + d] ++;
		last = d;
		s[i] = d + 'a';
	}
 
	for(int i = 0 ; i < n ; i ++)
		cout << s[i];
 
	return 0;
}

E題

想了半個小時也沒想出來,后面再補。
題意:

思路:
代碼如下


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM