训练交流.CodeForces.插入数字[中等][思路待扩宽]

 题目描述:


解题思路:题目是先输入一个参数t,表示需要判断的总数,然后每次输入三个数,分别是数串的位数n,需要插入的数d和数串本身ch,将d插入到ch中。

需要思考的点有两个,

一是读入这个数串,怎么读?

显然读成数组而且每个数单独存放,最方便后续判断。

输入一整个数,如果用int型放,显然需要拆分然后逐个放入数组里,很浪费时间,而且他给定的n范围到了2*10^5,用int显然行不通。

char型字符串满足要求,char字符串是按数组存储的而且默认就是一个萝卜一个坑。但是要注意用char型输入进来就是字符了,和要插入的数进行判断的时候要注意把串和数转换成相同的类型。(修订:直接把插入数按char型输入,比较的时候就不用考虑+-‘0’做转换的问题)

比如一开始要插入的数d用的int型,而数串ch用的char,那比较的时候要么int+‘0’和char比,要么char-‘0’之后和int比,要把这俩变成一样的类型。

二是怎么判断然后放入数组?

如果每个数都存放在单独的位置,遍历判断即可。

根据第一步的描述,为了方便比较,数串ch用char型字符串输入,如果待插入的数d也用char型输入,那么直接比较大小即可。

关于把数放入数组:我本来的构思是,判断 d>ch[i],一旦发现第一个小于d的数,就把d插入,数组其他数向后移动一位即可

和大佬交流的思路是,不用插入,遍历的同时进行判断,如果d<ch[i],就先把ch[i]输出,如果d>ch[i],就先把d输出,然后再把ch[i]输出。这样效果和插入数组再输出一样。

原思路是         挨个比较,插入,输出数组

现在更好的是  挨个比较,挨个输出

更节省时空。

代码示例如下:

//旧思路代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <iostream>
using namespace std;
#define MAX 100000

void Slove(void) {
	int n, num; 
	char sum[MAX]; //输入串存char
	int ch[MAX]; //串转为int
	scanf("%d %d", &n, &num);
	scanf("%s", &sum);
	for (int i = 0; i < n; i++) { //把输入数组由char转int
		ch[i] = sum[i] - '0';
	}
	for (int i = 0; i < n; i++) {
		if (ch[i] < num) { //找到插入位置
			for (int j = n; j > i; j--) {  //后续元素右移一位
				ch[j] = ch[j - 1];
			}
			ch[i] = num; //插入
			break;
		}else{ch[n]=num;} //没找到位置,把插入元素放在最后
	}
	for (int i = 0; i <= n; i++) { //打印整个串
		printf("%d", ch[i]);
	}
	return;
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--)
	{
		Slove();
	}
	return 0;
}
//新思路
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>
#include <stdio.h>
using namespace std;
#define MAX 200000
void Solve(void)
{
	int n;
	char d;  //待插入字符直接输入为char,方便比较
	scanf("%d %c", &n, &d);
	char ch[MAX];  //我的vs不支持c99,没法用ch[n],这里用宏定义
	scanf("%s", ch); //输入字串
	int flg = 0; //flag用来记录是否已经插入d
 
	for (int i = 0; i < n; ++i) {  //循环比较并输出
		if (d > ch[i] && flg == 0) { //if成立,就先输出d,然后输出后面的ch[i]
			printf("%c", d);
			flg = 1;
		}
		printf("%c", ch[i]);  //if不成立,就先输出ch[i]
	}
	if (!flg) { // flg没变,说明没找到插入位置,则最后输出d
		printf("%c", d);
	}
	printf("\n");
	return;
}

int main()
{
	int t;
	scanf("%d", &t);
	while (t--) {
		Solve();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值