/*输入描述:
一组输入整数序列I和一组规则整数序列R,I和R序列的第一个整数为序列的个数(个数不包含第一个整数);整数范围为0~(2^31)-1,序列个数不限
输出描述:
从R依次中取出R,对I进行处理,找到满足条件的I:
I整数对应的数字需要连续包含R对应的数字。比如R为23,I为231,那么I包含了R,条件满足 。
按R从小到大的顺序:
(1)先输出R;
(2)再输出满足条件的I的个数;
(3)然后输出满足条件的I在I序列中的位置索引(从0开始);
(4)最后再输出I。
附加条件:
(1)R需要从小到大排序。相同的R只需要输出索引小的以及满足条件的I,索引大的需要过滤掉
(2)如果没有满足条件的I,对应的R不用输出
(3)最后需要在输出序列的第一个整数位置记录后续整数序列的个数(不包含“个数”本身)
序列I:15,123,456,786,453,46,7,5,3,665,453456,745,456,786,453,123(第一个15表明后续有15个整数)
序列R:5,6,3,6,3,0(第一个5表明后续有5个整数)
输出:30, 3,6,0,123,3,453,7,3,9,453456,13,453,14,123,6,7,1,456,2,786,4,46,8,665,9,453456,11,456,12,786
说明:
30----后续有30个整数
3----从小到大排序,第一个R为0,但没有满足条件的I,不输出0,而下一个R是3
6— 存在6个包含3的I
0— 123所在的原序号为0
123— 123包含3,满足条件
输入:
15 123 456 786 453 46 7 5 3 665 453456 745 456 786 453 123
5 6 3 6 3 0
复制
输出:
30 3 6 0 123 3 453 7 3 9 453456 13 453 14 123 6 7 1 456 2 786 4 46 8 665 9 453456 11 456 12 786
复制
说明:
将序列R:5,6,3,6,3,0(第一个5表明后续有5个整数)排序去重后,可得0,3,6。
序列I没有包含0的元素。
序列I中包含3的元素有:I[0]的值为123、I[3]的值为453、I[7]的值为3、I[9]的值为453456、I[13]的值为453、I[14]的值为123。
序列I中包含6的元素有:I[1]的值为456、I[2]的值为786、I[4]的值为46、I[8]的值为665、I[9]的值为453456、I[11]的值为456、I[12]的值为786。
最后按题目要求的格式进行输出即可。*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define false 0
#define true 1
//快速排序算法
//input 数组首地址,开始下标,结束下标
//output 返回数组首地址
int* QuickSort(int* array, int begin, int end) {
if (begin > end)
return 0;
int x = array[begin];
int i = begin, j = end;
int temp;
while (i != j) {
while ((array[j] >= x) && (j > i))
j--;
while ((array[i] <= x) && (j > i))
i++;
//更改上面两个while循环的大于小于号可改变排序方向
//需要同时更改
if (j > i) {
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
array[begin] = array[i];
array[i] = x;
QuickSort(array, begin, i - 1);
QuickSort(array, i + 1, end);
return array;
}
//数组去重,要求已经排好序
//input 数组首地址 数组长度
//output 返回去重后数组的元素个数
int Deduplicate(int *array,int length)
{
int i;
int j = 0;
for(i = 0;i<length;i++)
{
if(array[j] != array[i])
{
j++;
array[j] = array[i];
}
}
//测试数组是否正确去重
// for (i = 0; i < j+1; i++)
// {
// printf("%d ", dealArray[i]);
// printf("\n");
// }
return j+1;
}
/*
调用该函数前应先将数组元素初始化0
将int整数每个位上的数字从后放入数组
例如:456转化为 0 0 0 0 0 0 0 4 5 6
input 转化后存放的数组,需要转化的int型整数
output 返回整数的位数
*/
int IntToArray(char array[],int num)
{
int i;
for( i = 9;i>=0;i--)
{
array[i] = num%10;
//printf("%d ", array[i]);
num = (num-array[i])/10;
if(num == 0)
break;
}
return 10-i;
}
/*判断num1是否包含num2*/
//input 包含整数1 被包含整数2
//output 是返回true,否返回false
char IsIncludeInt(int num1,int num2)
{
//测试输入是否正确
// printf("%d ", num1);
// printf("%d ", num2);
// printf("\n");
if(num1 == num2)return true;//两数相等肯定包含
if(num1 < num2)return false;//包含数比被包含数小肯定不包含
int i ,j;
int countNum1,countNum2;//num1,num2的位数
char array1[10] = {0},array2[10] = {0};//数组元素初始化为0
countNum1 = IntToArray(array1,num1);
countNum2 = IntToArray(array2,num2);
//测试函数是否正确执行
// printf("%d ", countNum1);
// printf("%d ", countNum2);
// printf("\n");
//测试转化后的数组是否符合预期
// while (i < countNum2) {
// printf("%d ", array2[9-i]);
// i++;
// }
// printf("\n");
// i = 0;
// while (i < countNum1) {
// printf("%d ", array1[9-i]);
// i++;
// }
int countflag = 0;
while(countflag<(countNum1-countNum2+1))
//最大循环次数 num1位数-num2位数+1
//例如,456 45,需要比较45,56与45是否相等,次数为2
{
i = 9-countflag;
j = 9;
while (j>9-countNum2)
//循环次数 num2的位数
//比较比较相同位数的num1与num2每个位是否相等
//是比较下个位,否直接退出循环
//从个位开始比较
{
//测试读取的位的数值是否正确
//printf("%d ", array1[i]);
//printf("%d ", array2[j]);
if(array1[i] == array2[j])
{
i--;
j--;
}
else
{
break;
}
}
//如果正常退出循环说明有相等的,直接返回true
if(j == 9-countNum2)
return true;
countflag++;
}
return false;
}
int main()
{
int R_len, I_len;//序列R,I的长度
int* Rarray;//序列R的首地址
int* Iarray;
int count;
int i,j,sum;
int *countArray;//存放输出数据
while (scanf("%d", &I_len) != EOF)
{
//输入处理
//为序列I申请相应的内存空间
Iarray = (int*)malloc(I_len * sizeof(int));
//将输入的序列I的值存放到申请的内存空间中
//相当于数组
for (count = 0; count < I_len; count++)
{
scanf("%d", Iarray + count);
}
scanf("%d", &R_len);
Rarray = (int*)malloc(R_len * sizeof(int));
for (count = 0; count < R_len; count++)
{
scanf("%d ", Rarray + count);
//printf("%d ", *(Rarray + count));
}
//从小到大排序
QuickSort(Rarray, 0, R_len-1);
//去重
R_len = Deduplicate(Rarray, R_len);
//审题可知输出最大长度R_len*I_len*2+1
countArray = (int *)malloc((R_len*I_len*2+1)*sizeof(int));
//初始化为0
memset(countArray,0,R_len*I_len*2+1);
//包含处理
int k = 0;
//可将countArray看成二位数组,R_len为行,I_len为列
for(i = 0;i<R_len;i++)
{
for(j = 0;j<I_len;j++)
{
if(IsIncludeInt(Iarray[j],Rarray[i]))
{
countArray[i*I_len]++;//存放包含个数
countArray[i*I_len+2*k+1] = j;//存放下标
countArray[i*I_len+2*k+2] = Iarray[j];//存放数值
k++;
}
}
k=0;
}
//计算输出整数的个数
sum = 0;
for(i = 0;i<R_len;i++)
{
sum = sum + countArray[i*I_len];
sum++;
if(countArray[i*I_len] == 0)
sum--;
}
sum = 2*sum;
//输出处理
printf("%d ",sum);
for(i = 0;i<R_len;i++)
{
if(countArray[i*I_len] != 0)
{
printf("%d ",Rarray[i]);
printf("%d ",countArray[i*I_len]);
}
for(j = 0;j<countArray[i*I_len];j++)
{
printf("%d ",countArray[i*I_len+2*j+1] );
printf("%d ",countArray[i*I_len+2*j+2] );
}
}
//动态内存释放
free(countArray);
free(Rarray);
free(Iarray);
//测试函数IsIncludeInt
//flag = IsIncludeInt(Iarray[1],Rarray[1]);
//flag = IsIncludeInt(987654321,654);
//printf("%d ",flag);
//测试序列R,I的值
// for (count = 0; count < R_len; count++) {
// printf("%d ", Rarray[count]);
// }
// printf("\n");
// for (count = 0; count < I_len; count++)
// {
// printf("%d ", Iarray[count]);
// }
}
return 0;
}