A. Vlad and the Best of Five(模拟)
思路
分别统计 A 和 B 的个数,输出个数多的
#include<iostream>
using namespace std;
int main(){
int t;
cin>>t;
string s;
while(t--){
cin>>s;
int a = 0, b = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] == 'A') a++;
else b++;
}
if(a >= b) cout<<'A'<<endl;
else cout<<'B'<<endl;
}
return 0;
}
B. Vlad and Shapes(思维)
思路
统计每一行有多少个1,如果连续存在的两行1的个数不同就是三角形,否则是正方形
#include<iostream>
using namespace std;
int main(){
int t;
cin>>t;
int n;
char g[11][11];
while(t--){
cin>>n;
int a[11] = {0};
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
cin>>g[i][j];
if(g[i][j] == '1') a[i]++;
}
}
int zz = 0, f = 1;
for(int i = 0; i < n; i++){
if(a[i] && f){
zz = a[i];
f = 0;
}else if(a[i] && f == 0){
if(a[i] == zz){
cout<<"SQUARE"<<endl;
f = 2;
break;
}
}
}
if(f != 2) cout<<"TRIANGLE"<<endl;
}
return 0;
}
C. Vlad and a Sum of Sum of Digits(前缀和)
思路
前缀和预处理每个数加之前的数之和
#include<iostream>
using namespace std;
int main(){
int a[200010] = {0};
for(int i = 1; i <= 200005; i++){
int z = i, zz = 0;
while(z){
zz += z % 10;
z /= 10;
}
a[i] = a[i - 1] + zz;
}
int t;
cin>>t;
int n;
while(t--){
cin>>n;
cout<<a[n]<<endl;
}
return 0;
}
D. Vlad and Division(排序、双指针)
思路
只有 x + y = 2 ^ 31 - 1 才可以分配到一组
#include<iostream>
#include<algorithm>
using namespace std;
const long long mod = (1 << 31) - 1;
long long a[200010];
int main(){
int t;
cin>>t;
int n;
while(t--){
cin>>n;
for(int i = 0; i < n; i++) cin>>a[i];
sort(a, a + n);
int l = 0, r = n - 1, ans = 0;
while(l < r){
if(a[l] + a[r] == mod){
ans++;
l++;
r--;
}
while(a[l] + a[r] > mod && l < r) r--;
while(a[l] + a[r] < mod && l < r) l++;
}
cout<<n - ans<<endl;
}
return 0;
}
E. Vlad and an Odd Ordering(思维)
思路
奇数一共有 (n + 1) / 2 个, 两倍的奇数有 (n / 2 + 1) / 2个 … 每次开头的数是 1、2、4、8 …
#include<iostream>
using namespace std;
int main(){
int t;
cin>>t;
int n, k;
while(t--){
cin>>n>>k;
int cnt = 1;
while((n + 1) / 2 < k){
k -= (n + 1) / 2;
n /= 2;
cnt *= 2;
}
//cnt是每次开头的数,k是第几个数
cout<<cnt * (2 * k - 1)<<endl;
}
return 0;
}
G. Vlad and Trouble at MIT(树形dp)
思路
ai < i,所以 i 从 2 开始
f[u][0]: 当前 u 节点的 子节点是 S 的所需隔板的最小值
f[u][1]: 当前 u 节点的 子节点是 P 的所需隔板的最小值
#include<iostream>
#include<vector>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 200005;
vector<int> G[N];
char s[N];
int f[N][2];
void dfs(int u) {
f[u][0] = f[u][1] = 0;
if (s[u] == 'P') f[u][0] = INF;
if (s[u] == 'S') f[u][1] = INF;
for (auto v : G[u]) {
dfs(v);
f[u][0] += min(f[v][0], f[v][1] + 1);
f[u][1] += min(f[v][1], f[v][0] + 1);
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) G[i].clear();
for (int i = 2; i <= n; i++) {
int x;
scanf("%d", &x);
G[x].push_back(i);
}
scanf("%s", s + 1);
dfs(1);
printf("%d\n", min(f[1][0], f[1][1]));
}
return 0;
}