1. 程式人生 > 其它 >Codeforces Round #786 (Div. 3) - 題解

Codeforces Round #786 (Div. 3) - 題解

A. Number Transformation

題目傳送門

翻譯

  • \(t\) 組資料,每組資料給定兩個正整數 \(x, y\),要求構造出 \(a, b\) 使得 \(x \cdot b^a = y\),如果無解則輸出 \(0\)
  • \(1 \leq t \leq 10^4, 1 \leq x, y \leq 100\)

Solution

送分題。

首先判無解。考慮到 \(b^a\) 必定為正整數,所以如果 \(x \nmid y\),則無解。

如果有解,則說明 \(\frac{y}{x}\) 為正整數。那麼我們構造 \(a = 1, b = \frac{y}{x}\) 就好啦。

Code

#include <bits/stdc++.h>
using namespace std;

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (!isdigit(ch)) f = (ch == '-' ? -1 : f), ch = getchar();
    while (isdigit(ch)) x = (x<<3) + (x<<1) + ch - '0', ch = getchar();
    return x*f;
}

int t, x, y; 

signed main() {
    t = read();
    while (t--) {
	x = read(), y = read();
	if (y%x) printf("0 0\n");
	else printf("1 %d\n", y/x);
    }
}

B. Dictionary

題目傳送門

翻譯

  • 有一門神奇的語言,每個單詞只有兩個互不相同的小寫字母組成。
  • 這門語言的詞典裡包含了所有的單詞,單詞按字典序排列。詞典如下所示:
    • 單詞 \(1\)\(\texttt{ab}\)
    • 單詞 \(2\)\(\texttt{ac}\)
      ...
    • 單詞 \(25\)\(\texttt{az}\)
    • 單詞 \(26\)\(\texttt{ba}\)
    • 單詞 \(27\)\(\texttt{bc}\)
      ...
    • 單詞 \(649\)\(\texttt{zx}\)
    • 單詞 \(650\)\(\texttt{zy}\)
  • 現在給你這門語言的一個單詞 \(s\)
    ,你需要求出它在詞典裡排第幾個。
  • \(t\) 組資料。 \(1 \leq t \leq 650\)

Solution

我們知道,以 \(a\) 打頭的單詞有 \(25\) 個,以 \(b\) 打頭的單詞也有 \(25\) 個,...,以 \(z\) 打頭的單詞也有 \(25\) 個。

那麼,第一個字母與 \(s\) 不同且排在 \(s\) 前面的單詞就有 \((\)$s_0 - $' \(\texttt{a}\) ' \() \ \times \ 25\) 個。

接下來我們求出第一個字母與 \(s\) 相同且排在 \(s\) 前面的單詞個數即可。

  • 如果 \(s_0 < s_1\),那麼顯然有 $s_1 - $' \(\texttt{a}\) ' 個。
  • 如果 \(s_0 > s_1\),那麼顯然有 $s_1 - $' \(\texttt{a}\) ' \(+ \ 1\) 個。

問題也就迎刃而解了。

Code

#include <bits/stdc++.h>
using namespace std;

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (!isdigit(ch)) f = (ch == '-' ? -1 : f), ch = getchar();
    while (isdigit(ch)) x = (x<<3) + (x<<1) + ch - '0', ch = getchar();
    return x*f;
}

string s;
int t;

signed main() {
    t = read();
    while (t--) {
	cin >> s;
	if (s[0] > s[1])
	    printf("%d\n", (s[0]-'a')*25+s[1]-'a'+1);
	else printf("%d\n", (s[0]-'a')*25+s[1]-'a');
    }
}


C. Infinite Replacement

題目傳送門

翻譯

  • 給定僅由 '\(\texttt{a}\)' 組成的字串 \(s\) 和由小寫字母組成的字串 \(t\)
  • 你可以執行任意次操作。每次操作你可以選擇 \(s\) 中的一個字元 '\(\texttt{a}\)' 並將其換成字串 \(t\)
  • 你需要求出你最終可以得到多少個不同的 \(s\)。如果答案是無窮大,輸出 \(-1\)
  • \(q\) 組資料。\(1 \leq q \leq 10^4\)\(s, t\) 的長度不超過 \(50\),保證 \(s\)\(t\) 非空。

Solution

首先思考什麼時候答案為無窮大。

考慮這樣一種情況,\(t\) 中包含了字元 '\(\texttt{a}\)':

  • 如果 \(t\) 的長度為 \(1\),那麼字串 \(s\) 無論如何都不會改變。此時答案為 \(1\)
  • 如果 \(t\) 的長度不為 \(1\),此時答案無窮大。
    比如 $s = $ " \(\texttt{a}\) ",$t = $ " \(\texttt{ab}\) ",那麼 \(s\) 就可以 " \(\texttt{a}\) " \(\rightarrow\) " \(\texttt{ab}\) " \(\rightarrow\) " \(\texttt{aab}\) " ...... 這樣無窮變化下去。

其餘情況下,根據子集相關知識,答案顯然為 \(2^k\),其中 \(k\)\(s\) 的長度。

注意要開 long long

Code

#include <bits/stdc++.h>
#define int long long 
using namespace std;

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (!isdigit(ch)) f = (ch == '-' ? -1 : f), ch = getchar();
    while (isdigit(ch)) x = (x<<3) + (x<<1) + ch - '0', ch = getchar();
    return x*f;
}

const int L = 2e5 + 5;
string s, t;
bool f;
int q; 

signed main() {
    q = read();
    while (q--) {
	cin >> s >> t;
	f = 0;
	for (int i = 0; i < t.size(); i++)
	    if (t[i] == 'a') f = 1;
			
	if (f) {
	    if (t.size() == 1) 
		puts("1");
	    else puts("-1");
	} else
	    printf("%lld\n", (1LL<<s.size()));
    }
}


D. A-B-C Sort

作者咕了,下次一定更。


E. Breaking the Wall

作者咕了,下次一定更。