题目描述:
解题思路:题目是先输入一个参数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;
}