A. Number Transformation
题意:有 T 组数据,给定 , ,是否存在 , 存在输出 ,, 否则输出 0 0。
#include <iostream>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int x, y;
cin>>x>>y;
if(y%x != 0){
cout<<0<<" "<<0<<endl;
}else{
int t = y/x;
cout<<1<<" "<<t<<endl;
}
}
return 0;
}
B. Dictionary
题意: 2个字母的字典升序, 从 1 开始, 输入2个字母, 找出在字典的位置。 注意去掉相同字母。
#include <iostream>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
string s;
cin>>s;
int res = (s[0]-'a')*26+(s[1]-'a');
res -= s[0] -'a';
if(s[1] > s[0]){
res --;
}
cout<<res+1<<endl;
}
return 0;
}
C. Infinite Replacement
题意:给一个字符串 和字符串 ,中的字符 a 可以替换成 t 或者不替换,问有多少种替换方式,如果是无限多个返回-1。
分情况讨论:
- t 的长度为 1,并且字符为 a, 返回 1。
- t 的长度大于 1,并且 t 中包含字符 a, 可以组成无限长,返回 -1。
- 判断 s 串中字符 a 的个数, pow(2, count(a))。 注意开 long long。
#include <iostream>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
string a, b;
cin>>a>>b;
if(b.find('a') != string::npos){
if(b.size() == 1){
cout<<1<<endl;
}else cout<<-1<<endl;
}else{
int cnt = 0;
for(auto& c : a){
if(c == 'a') cnt++;
}
long long res = 1;
for(int i=1; i<=cnt; i++){
res *=2;
}
cout<<res<<endl;
}
}
return 0;
}
D. A-B-C Sort
题意:有 3个数组, a, b, c, a 有 n个元素, b, c是空的。
有以下2个步骤:
- a 不为空时,将追后一个元素移动到 b 数组的中间,如果 b 数组的长度为奇数,可以放到中的左边或者中的右边。
- 当 b 不为空时,将 b 中间的元素移动到 c 数组的后面,如果 b 数组的长度为偶数时,中间的2个值随便取一个。
判断 c 数组是否可以为升序的数组?
通过模拟数据,只需要 a 数组中的长度2 数值交换,可以组成升序,那么 c 就可以组成升序。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2e5+10;
int a[N], b[N];
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0; i<n; i++) cin>>a[i], b[i] = a[i];
for(int i=n-1; i>0; i-=2){
if(a[i] < a[i-1]){
swap(a[i], a[i-1]);
}
}
sort(b, b+n);
bool flag = true;
for(int i=0; i<n; i++){
if(a[i] != b[i]){
cout<<"NO"<<endl;
flag = false;
break;
}
}
if(flag) cout<<"YES"<<endl;
}
return 0;
}
E. Breaking the Wall
题意: 用炮弹去炸墙,墙是是一个大小为 n 的数组组成, 每一个数值代表的这墙的生命值,如果生命值小于等于 0 ,这一块就穿了, 攻击城堡需要两处生命值为 0, 一个炮弹打到 x 处,x 出的生命值 -2, 处的生命值减 -1,问需用最少多少个炮弹炸出两个坑。
分情况讨论:
- 找 2 处最小的值的地方炸就完事, + 。
- 找 2 处相邻的地方炸
- 第一种 ,
- 第二种 , 轰炸一次, 相当于 和 整体 ,所以
- 找 和 , 炸 处, 如果 和 为 奇数,则选择花费一次操作令它们都减少 ,。
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 2e5+10;
int a[N];
int main(){
int n;
cin>>n;
for(int i=0; i<n; i++) cin>>a[i];
int min1 = 1e6+5, min2 = 1e6+5;
// 找最小值和次小值
for(int i=0; i<n; i++){
if(min1 >= a[i]){
if(min1 <= min2) min2 = min1;
min1 = a[i];
}else{
if(a[i] <= min2) min2 = a[i];
}
}
// 不相邻最小2个点
int minv = (min1+1)/2+(min2+1)/2;
// 相邻的 2个点
for(int i=0; i<n-1; i++){
int t1 = a[i], t2 = a[i+1];
if(t1 < t2) swap(t1, t2);
if(t1 >= 2*t2) {
minv = min(minv, (t1+1)/2);
}else{
minv = min(minv, (int)ceil((t1+t2)/3.0));
}
}
// a[i-1] && a[i+1]
for(int i=1; i<n-1; i++){
int t1 = a[i-1], t2 = a[i+1];
if(t1%2 && t2%2){
minv = min(minv, (t1+t2)/2);
}
}
cout<<minv<<endl;
return 0;
}
F. Desktop Rearrangement
题意:给一个 的二维数组, 和 '.' 组成,如果 都是按列全部填充,或者第一列填满,到下一列,都认为是 good, 可以任意移动位置,算作一次。 给 q 个询问, , 为坐标,如果 , 处为 , 改为‘.’,如果 , 处为'.', 将改成 , 等需要移动多少个'*'。
统计所有的 * 的个数 cnt, 统计每一列的 * 的 个数 cols, 将对应 , 位置进行改变,
统计在 列 行, * 的个数 , 就是在这个区间之外的 *, 也就是需要移动的个数。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1005;
char g[N][N];
int col[N];
int main(){
int n, m, q, cnt = 0;
cin>>n>>m>>q;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++){
cin>>g[i][j];
if(g[i][j] == '*'){
cnt++;
col[j]++;
}
}
while(q--){
int x, y;
cin>>x>>y;
x--; y--;
if(g[x][y] == '*'){
g[x][y] = '.';
cnt--;
col[y]--;
}else g[x][y] = '*', cnt++, col[y]++;
int sum = 0;
int a = cnt/n, b = cnt%n;
for(int i=0; i<a; i++){
sum += col[i];
}
for(int i=0; i<b; i++){
if(g[i][a] == '*') sum++;
}
cout<<cnt - sum<<endl;
}
return 0;
}