Codeforces Round #762 (Div. 3)

A. Square String?

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

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

C. Wrong Addition

题目给定我们a和s,要求我们根据它的计算规则求b

题目分析:

我们令ai,bi,si分别表示a,b,s的第 i 位数字,我们分别从a和s的尾部开始计算。并令x表示ai,y表示si。

  1. 当x < y时,直接计算bi = y - x;
  2. 当x > y时,y的值不够大,我们要想前一位借数,令y += (s % 10) * 10,这时我们要判断两种情况:
    1… 当y >= 10 && y <= 18时,符合条件,将y - x放入数组
    2…当y > 18时,说明找不到符合条件的b,因为0 <= ai + bi <= 18
  3. 如果当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;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

友人苏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值