C language: Brush question summary

Posted by Brad on Sat, 05 Mar 2022 12:39:07 +0100

C language learning has come to an end. This paper is a summary of the recent learning of C language. Most of the questions come from niuke.com.

This article is the last article in this stage of C language. After several months of study, I will write some blogs about Java. If I have the opportunity later, I will continue to improve the content of C language.

Topic 15: number pairs

Title Description: a positive integer number pair (x,y), the values of X and y are not greater than n, and the value of x%y is greater than or equal to k.

Input Description: the input includes two positive integers n, K (1 < = n < = 10 ^ 5, 0 < = k < = n - 1).
Output Description: for each test case, output a positive integer to represent the number of possible pairs.

Idea: the initial idea was to directly use two cycles to solve the matching number pairs, but the time was too complex, so the compilation failed. Here, another idea is introduced through an example: suppose the input n = 10, k = 3;
When y < = k, it means that the result of any digital modulus y is between [0, k-1], which is not qualified.
When y = k+1=4, the number of qualified x is 3,7
When y = k+2=5, the qualified numbers of x are 3,4,8,9
When y = k+3=6, the qualified numbers of x are 3,4,5,9,10
When y = k+n,
x is less than the current value of y, and the number of qualified numbers is: y-k,
The number of qualified numbers in the data where x is greater than the current value of Y and less than 2*y is: y-k
As can be seen from the previous step, in the integer multiple interval of Y, the number of qualified x is (n / y) * (y - k)
n / y indicates how many complete 0 ~ y intervals there are, and y - k indicates how many qualified numbers there are in each interval
The last thing to consider is 6 In the future, the statistics of the part exceeding the multiple interval exceeding n
N% y is the number of more numbers than the complete interval. If the number below K is not considered, then n% Y - (k-1) are qualified
It should be noted here that if the number of numbers beyond the complete interval is less than k, such as 9, it is 0
Get the final formula: (n / y) * (Y - K) + (n% y < K)? 0, (n % y - k + 1));

Implementation code:

#include <stdio.h>
int main()
{
	long n = 0;
	long k = 0;
	scanf("%ld %ld", &n, &k);
	if (k == 0)
	{
		printf("%ld\n", n * n);
	}
	else
	{
		long count = 0;
		for (long y = k + 1; y <= n; y++)
		{
			count += ((n / y) * (y - k)) + ((n % y < k) ? 0: (n % y - k + 1));
		}
		printf("%ld\n", count);
	}
	return 0;
}

Topic 16: rotation string problem - left rotation string

Title Description: enter k and output the string after turning left to k characters

Idea 1: in the conventional method, save the first character, move other characters forward by one bit, and finally copy the saved character to the last, and cycle k times in turn to get the result

Implementation code:

#include <stdio.h>
#include <string.h>

void left_move(char* arr, int k)
{
	int len = strlen(arr);
	while (k--)
	{
		char ret = *arr;
		int i = 0;
		for (i = 0; i < len - 1; i++)
		{
			*(arr + i) = *(arr + i + 1);
		}
		*(arr + len - 1) = ret;
	}
}

int main()
{
	char arr[] = "abcdef";
	int k = 0;
	scanf("%d", &k);
	left_move(arr, k);
	printf("%s\n", arr);
	return 0;
}

Idea 2: rotate in reverse order. If you rotate the k-bit, separate the string into two strings at the k-bit position, then reverse the two strings respectively, and finally reverse the whole string again. You can also get the result

Implementation code:

void reverse(char* left, char* right)
{
	while (left < right)
	{
		char ret = *left;
		*left = *right;
		*right = ret;
		left++;
		right--;
	}
}

void left_move(char* arr, int k)
{
	int len = strlen(arr);
	k %= len;
	reverse(arr, arr + k - 1);
	reverse(arr + k, arr + len - 1);
	reverse(arr, arr + len - 1);
}

int main()
{
	char arr[] = "abcdef";
	int k = 0;
	scanf("%d", &k);
	left_move(arr, k);
	printf("%s\n", arr);
	return 0;
}

Title: Yang's matrix

Title Description: there is a three-dimensional array. Each row of the array is incremented from left to right, and each column is incremented from top to bottom. Find out whether a number exists in this array.

Idea: the simplest and most violent idea of this topic is to traverse the entire three-dimensional array directly, but sometimes it can't pass the test case, Here is a conventional idea with low time complexity - only two of the nine elements of the three-dimensional Young's matrix are consistent (the two elements of the diagonal vertex, that is, the three elements of the first row and the first column of the third row and the first column of the third row). Any one of them can be selected. Here I use the elements of the first row and the third column (temporarily called K), If the search number is less than the value of K, you can search the two elements in front of K. if it is greater than k, you can find the elements in the next row of this column, and then repeat the above comparison until you find the element to be searched and return the coordinates of the element. If the search exceeds the limit of the three-dimensional array, you can judge that there is no such number in the array.

Implementation code:

#include <stdio.h>

void find_int_arr(int arr[3][3], int* px, int* py, int k)
{
	int x = 0;
	int y = *py - 1;
	while (x <= *px - 1 || y >= 0)
	{
		if (arr[x][y] > k)
		{
			y--;
		}
		else if (arr[x][y] < k)
		{
			x++;
		}
		else
		{
			*px = x;
			*py = y;
			return;
		}
	}
	*px = -1;
	*py = -1;
	return;
}

int main()
{
	int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
	int k = 0;
	int x = 3;
	int y = 3;
	scanf("%d", &k);
	find_int_arr(arr, &x, &y, k);
	if (x == -1 && y == -1)
	{
		printf("can't find\n");
	}
	else
	{
		printf("Yes, the subscript is:(%d,%d)", x, y);
	}
	return 0;
}

Title 18: looking for a single dog

Title Description: only two numbers in an array appear once, and all other numbers appear twice. Write a function to find these two numbers that appear only once.

Idea: we already know in the previous topic: just put all the numbers in the array together, and you can find the numbers that only appear once in the array. However, this question is different from the previous one. Generally speaking, it will increase the difficulty, because the question is to find two numbers in the array that only appear once. At first glance, it feels very similar, but think carefully. If all XORs are added as before, only a wrong value can be obtained, So here comes an idea - that is, divide the array into two parts, divide the two numbers that only appear once into two groups, and then find out the XOR respectively. So how to identify and divide the two numbers into two groups? The first step is to XOR all the numbers in the array; The second step is to find the binary after XOR. If the bit after XOR is 1 and the value after 1 is 1, it can indicate that the two numbers that only appear once are different in binary, and it will be 1 after XOR; The third step is to divide the binary into two groups based on the different bits just obtained. The two numbers that only appear once are divided into different groups. In this way, the final result can be obtained.

Implementation code:

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//1. Put all numbers together first
	int ret = 0;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		ret ^= arr[i];
	}
	//2. Which binary bit of ret is 1
	int pos = 0;
	for (i = 0; i < 32; i++)
	{
		if (((ret >> i) & 1) == 1)
		{
			pos = i;
			break;
		}
	}
	//3. Group the arrays according to whether the pos bit is 0 or 1
	int n = 0;
	int m = 0;
	for (i = 0; i < sz; i++)
	{
		if (((arr[i] >> pos) & 1) == 1)
		{
			n ^= arr[i];
		}
	}
	m = ret ^ n;
	printf("%d %d\n", n, m);
	return 0;
}

Title 19: judge whether a string is obtained by rotating another string

Title Description: judge whether a string is obtained by rotating another string

Idea: most people are influenced by the rotating string code before. The first idea of this problem should be to rotate the string first and then judge whether it is equal. Such a cycle. However, there is a simpler method for this problem - copy its own string and add it to the following position, and then find it through the string to determine whether it exists, so as to solve this problem.

Implementation code:

#include <stdio.h>
#include <string.h>
int main()
{
	char str[20] = "abcde";
	char* sub = "cdeab";
	char* tmp = strncat(str, str, 5);
	char* ret = strstr(tmp, sub);
	if (ret == NULL)
	{
		printf("can't find\n");
	}
	else
	{
		printf("%s\n", ret);
	}
	return 0;
}

Topics: C Back-end