Codeforces Round #762
A. Square String?
题目分析:
这道题的要求是,给定一个字符串,判断该字符串能否从中间被分为两部分,且左右两边相等,例如:“aaaa”, “abab”,简单的签到题。
思路分析:
首先我们要知道,长度为奇数的字符串一定不符合条件,所以我们只需判断长度为偶数字符串,我们将其从用双指针i = 0, j = mid,不断进行遍历,如果遇到不相等的则直接打印NO,并结束此次循环。
代码如下:
#include <iostream>
#include <cstring>
using namespace std;
int main(){
int t;
cin >> t;
while(t--){
char s[105];
cin >> s;
int slen = strlen(s);
if(slen % 2){
cout << "NO" << endl;
continue;
}
int mid = slen / 2;
bool flag = true;
int n = mid;
for(int i = 0; i < n; i++){
if(s[i] != s[mid]){
flag = false;
cout<< "NO" << endl;
break;
}
mid++;
}
if(flag){
cout<< "YES" << endl;
}
}
return 0;
}
B. Squares and Cubes
题目分析:
这道题是给定一个数字n,计算出在n之前有多少个数开方后是整数或三次开方后是整数的数。
思路分析:
首先,这道题的数据范围是1~10e9,很明显,是少要用小于O(n²)的时间复杂度,所以正面暴力不可取,转换一下,要判断一个数开方后是否为整数的时间复杂度至少O(logn),一个一个判断肯定不行,所以我们要将10e9以内的数字记录下来,不判断能否开方为整数,而是令 i 从1到√10e9进行遍历把所有i * i的数记录到数组中,同时记录i * i * i,这个过程的时间复杂度为O(1),然后我们就可以找出最后一个小于或等于n的数,其下标就是我们所求的值。
代码如下:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 33000;
const int M = 1000000000;
int squres[N], cubes[N], nums[N];
int squresSize = 0, cubesSize = 0, numsSize = 1;
void Get(){
//记录10^9以内开方
for (int i = 1; i * i <= M; i++){
squres[squresSize++] = i * i;
}
squres[squresSize] = M;
//计入10^9以内的三次根号
for (int i = 1; i * i * i<= M; i++){
cubes[cubesSize++] = i * i * i;
}
cubes[cubesSize] = M;
int i = 0, j = 0;
//升序和并,且消除冗余
while (i < squresSize && j < cubesSize){
if (squres[i] < cubes[j]){
nums[numsSize++] = squres[i];
i++;
}
else if (squres[i] > cubes[j]){
nums[numsSize++] = cubes[j];
j++;
}
else{
nums[numsSize++] = squres[i];
i++; j++;
}
}
nums[numsSize++] = M;
//cout << squres[squresSize - 1] << endl;
//cout << cubes[cubesSize - 1] << endl;
}
int main(){
int t;
cin >> t;
Get();
while (t--){
int n;
cin >> n;
int index = 1;
for (; index < numsSize; index++){
if (nums[index] == n){
break;
}
else if (nums[index] > n){
index -= 1;
break;
}
}
cout << index << endl;
}
return 0;
}
C. Wrong Addition
题目给定我们a和s,要求我们根据它的计算规则求b
题目分析:
我们令ai,bi,si分别表示a,b,s的第 i 位数字,我们分别从a和s的尾部开始计算。并令x表示ai,y表示si。
- 当x < y时,直接计算bi = y - x;
- 当x > y时,y的值不够大,我们要想前一位借数,令y += (s % 10) * 10,这时我们要判断两种情况:
1… 当y >= 10 && y <= 18时,符合条件,将y - x放入数组
2…当y > 18时,说明找不到符合条件的b,因为0 <= ai + bi <= 18- 如果当s已经变为0,而a还未取尽,也说明不存在b
代码如下:
#include <iostream>
using namespace std;
#define ll long long
void printNum(int* nums, int numsSize){
bool f = true;
for (int i = numsSize - 1; i >= 0; i--){
if (!nums[i] && f)continue;
else{
f = false;
cout << nums[i];
}
}
cout << endl;
}
int main(){
int t;
cin >> t;
while (t--){
ll a, s;
cin >> a >> s;
int b[20], bSize = 0;
int i = 0, j = 0;
bool f = true;
while(s){
int x = a % 10;
int y = s % 10;
a /= 10;
s /= 10;
if(x <= y)b[bSize++] = y - x;
else{
y += s % 10 * 10;
s /= 10;
if(x < y && y >= 10 && y <= 18){
b[bSize++] = y - x;
}
else{
f = false;
cout << -1 << endl;
break;
}
}
}
if(!f)continue;
if(a)cout << -1 << endl;
else printNum(b, bSize);
}
return 0;
}