A. Floor Number
大意:
第一層有2個房間,其它層都有x個房間,問第n個房間在第幾層
思路:
向上取整即可
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int t;
int main(){
cin >> t;
while(t--){
int n, x;
cin >> n >> x;
if (n <= 2) cout << 1 << endl;
else{
cout << 1 + ceil((1.0*n - 2) / x) << endl;
}
}
return 0;
}
B. Symmetric Matrix
大意:
給出n種2x2的小矩陣,問能否用這些矩陣組成一個kxk的主對角線對稱矩陣
思路:
當k爲奇數的時候無解
否則只要有一個小對稱矩陣即可,因爲可以都用這個小對稱矩陣填充
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int t;
int main() {
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
int flag = 0;
while (n--) {
int x1, x2, x3, x4;
cin >> x1 >> x2 >> x3 >> x4;
if (x2 == x3) flag = 1;
}
if (flag == 1 && ((m & 1) == 0))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
C. Increase and Copy
大意:
一個數組一開始只有一個元素1
現在每次可以做一個操作:
選擇一個元素使其+1
或者選擇一個元素,複製一份加到數組裏
問最少用幾次操作就可以使得數組元素的和不少於n
思路:
可以想到是先一直使一個元素+1,然後一直複製這個元素即可
最少操作次數可以通過枚舉加到幾來更新
只需要枚舉到sqrt(n)即可
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int t;
int main() {
cin >> t;
while (t--) {
int n, res = 0x3f3f3f3f;
cin >> n;
for (int i = 1; i <= sqrt(n); i++) {
int tmp = i - 1;
tmp += ceil((1.0 * n - i) / i);
res = min(res, tmp);
}
cout << res << endl;
}
return 0;
}
D. Non-zero Segments
大意:
給出n個數,問至少插入幾個數,可以使得數列裏面不存在和爲0的區間
思路:
利用前綴和,如果\(sum[l-1]=sum[r]\),那麼代表l到r這一區間的和爲0,所以只需要用map記錄一下前綴和即可
注意每次找到區間後要清空map
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int n, res;
map<LL, int> mp;
int main() {
cin >> n;
LL sum = 0;
mp[0] = 1;
while (n--) {
LL x;
cin >> x;
sum += x;
if (mp[sum]) {
res++;
sum = x;
mp.clear();
mp[0] = 1;
}
mp[sum]++;
}
cout << res << endl;
return 0;
}
E. Rock, Paper, Scissors
大意:
a和b玩石頭剪刀布,給出a和b出石頭、剪刀、布的數量,問a最少贏多少次,最多贏多少次
思路:
貪心的想,想讓a贏得最少,那麼就要把它最多數量的那個方法抵消掉,也就是說如果抵消不了剩下的就是最多能贏的次數
贏得最多,只需要讓每種出法都儘可能贏最多次即可
(本來寫了排序,結果發現不需要....結構體就沒刪)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int n;
struct node {
int type;
LL num;
} a[3], b[3], b2[3];
int main() {
cin >> n;
for (int i = 0; i < 3; i++) {
cin >> a[i].num;
a[i].type = i;
}
for (int i = 0; i < 3; i++) {
cin >> b[i].num;
b[i].type = i;
}
LL res2 = 0;
for (int i = 0; i < 3; i++) {
res2 += min(a[i].num, b[(i + 1) % 3].num);
}
LL res1 = 0;
for (int i = 2; i >= 0; i--) {
int tmp = 0;
for (int j = 0; j <= 2; j++) {
if ((a[i].type + 1) % 3 != b[j].type) {
tmp += b[j].num;
}
}
if (tmp < a[i].num) {
res1 = a[i].num - tmp;
}
}
cout << res1 <<' '<<res2<< endl;
return 0;
}
F. Number of Subsequences
大意:
給出一個長度爲n的字符串,其中有若干?,?的地方可以填abc中的任意字母
問填完?所得到的字符串集中,有多少個abc子序列
思路:
考慮dp
\(dp[0]\)代表字符串的數量
\(dp[1]\)代表字符串中子序列"a"的數量
\(dp[2]\)代表字符串中子序列"ab"的數量
\(dp[3]\)代表字符串中子序列"abc"的數量
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const int mod = 1e9 + 7;
typedef long long LL;
int n;
string s;
LL dp[5];
int main() {
cin >> n;
dp[0] = 1;
for (int i = 1; i <= n; i++) {
char x;
cin >> x;
if (x == 'a') dp[1] = (dp[1] + dp[0]) % mod;
if (x == 'b') dp[2] = (dp[2] + dp[1]) % mod;
if (x == 'c') dp[3] = (dp[3] + dp[2]) % mod;
if (x == '?') {
dp[3] = (3 * dp[3] % mod + dp[2]) % mod;
dp[2] = (3 * dp[2] % mod + dp[1]) % mod;
dp[1] = (3 * dp[1] % mod + dp[0]) % mod;
dp[0] = 3 * dp[0] % mod;
}
}
cout << dp[3] << endl;
return 0;
}