中北大学阿尔法编程之分治算法

整数划分问题

整数划分问题:将一个整数划分为若干个数相加

例子:

整数4 最大加数 4

4=4

1+3=4

1+1+2=4

2+2=4

1+1+1+1=4

一共五种划分方案

注意:1+3=4,3+1=4被认为是同一种划分方案

最后输出共几种划分方案

#include <stdio.h>

int q(int n, int m) {

if (m == 1 || n == 1) {

return 1;

} else if (n == m && n > 1) {

return q(n, n - 1) + 1;

} else if (n < m) {

return q(n, n);

} else if (n > m) {

return q(n, m - 1) + q(n - m, m);

}

return 0;

}

int main() {

printf("请输入需要划分的数字和最大加数:\n");

int n, m;

scanf("%d %d", &n, &m);

int r = q(n, m);

printf("%d\n", r);

return 0;

}

使用减治法计算多边形的面积

给定一个多边形的顶点坐标,要求使用减治法计算该多边形的面积。

要求:

1.实现一个函数 double calculateArea(double x[], double y[], int n),其中 x[] 和 y[] 分别是多边形各顶点的 x 坐标和 y 坐标数组,n 是多边形的顶点个数。

2.使用减治法思想,将多边形分解为三角形,计算每个三角形的面积,然后将所有三角形的面积相加得到多边形的面积。

3.返回多边形的面积。

#include <stdio.h>

#include <math.h>

double triangleArea(double x1, double y1, double x2, double y2, double x3, double y3) {

return fabs((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2.0);

}

double calculateArea(double x[], double y[], int n) {

double area = 0.0;

for (int i = 1; i < n - 1; i++) {

area += triangleArea(x[0], y[0], x[i], y[i], x[i + 1], y[i + 1]);

}

return area;

}

int main() {

int n;

printf("请输入多边形的顶点个数:");

scanf("%d", &n);

double x[n], y[n];

printf("请输入多边形的各顶点坐标:\n");

for (int i = 0; i < n; i++) {

printf("顶点%d的坐标(x,y):", i + 1);

scanf("%lf %lf", &x[i], &y[i]);

}

//计算多边形的面积

double area = calculateArea(x, y, n);

printf("多边形的面积为:%.2lf\n", area);

return 0;

}

拿子游戏

拿子游戏是一个经典的博弈论问题,有一个堆中有一定数量的子,两个玩家轮流从中取子,每次可以取走 1 到 k 个子,最后无法取子的一方判负。现在要求你使用分治法或减治法来解决这个问题。

要求:

1.实现一个函数 int canWin(int n, int k),其中 n 是初始子的数量,k 是每次最多可以取走的子的数量。

2.使用分治法或减治法思想,递归地判断当前玩家是否能赢得游戏。

3.返回值为 1 表示当前玩家能赢得游戏,返回值为 0 表示当前玩家无法赢得游戏。

#include<stdio.h>

#include <limits.h>

int canWin(int n, int k)

{

if(n<=k)

return 1;

if(n%(k+1)==0)

return 0;

return !canWin(n-(n%(k+1)),k);

}

int main(){

int n,k;

printf("请输入初始子的数量n和每次最多可以取走的子的数量k:\n");

scanf("%d %d",&n,&k);

int result=canWin(n,k);

if(result){

printf("当前玩家能赢得游戏!\n");

}

else{

printf("当前玩家无法赢得游戏!\n");

}

return 0;//请在此处开始编写你的代码

}

棋盘覆盖问题

棋盘覆盖问题是一个经典的计算几何问题,给定一个 2^k x 2^k 的棋盘和一个特殊方块,要求用特殊方块覆盖整个棋盘,其中特殊方块除了一个缺口外都是完整的 L 形。现在要求你使用分治法或减治法来解决这个问题。

要求:

1.实现一个函数 void chessboardCover(int board[][MAX], int tr, int tc, int dr, int dc, int size),其中 board 是二维数组表示棋盘,tr 和 tc 是棋盘左上角的行和列,dr 和 dc 是特殊方块的缺口所在的行和列,size 是当前棋盘的大小。

2.使用分治法或减治法思想,将棋盘划分为四个等大小的子棋盘,递归地覆盖子棋盘,直到覆盖完整个棋盘。

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

int num = 0,x=2;

int Matrix[100][100];

void chessBoard(int tr, int tc, int dr, int dc, int size);

int main()

{

int size,r,c,row,col;

//printf("请输入棋盘的行列号");

scanf("%d",&size);

size= pow(x,size);

//printf("请输入特殊方格的行列号");

scanf("%d %d",&row,&col);

chessBoard(0,0,row,col,size);

for (r = 0; r < size; r++)

{

for (c = 0; c < size; c++)

{

printf("%2d ",Matrix[r][c]);

}

printf("\n");

}

return 0;

}

void chessBoard(int tr, int tc, int dr, int dc, int size)

{

int s,t;

if (size==1) return;

s = size/2;    //分割棋盘

t = ++num;      //L型骨牌号

if (dr < tr + s && dc < tc +s)                //覆盖左上角子棋盘

{

//特殊方格在此棋盘中

chessBoard(tr,tc,dr,dc,s);

}

else            //此棋盘中无特殊方格

{

//用t号L型骨牌覆盖右下角

Matrix[tr+s-1][tc+s-1] = t;

//覆盖其余方格

chessBoard(tr,tc,tr+s-1,tc+s-1,s);

}

//覆盖右上角子棋盘

if (dr < tr + s && dc >= tc + s )           //

{

//特殊方格在此棋盘中

chessBoard(tr,tc+s,dr,dc,s);

}

else      //此棋盘中无特殊方格

{

//用t号L型骨牌覆盖左下角

Matrix[tr+s-1][tc+s] = t;

//覆盖其余方格

chessBoard(tr,tc+s,tr+s-1,tc+s,s);

}

//覆盖左下角子棋盘

if (dr >= tr + s && dc < tc + s)

{

//特殊方格在此棋盘中

chessBoard(tr+s,tc,dr,dc,s);

}

else

{

//用t号L型骨牌覆盖右上角

Matrix[tr+s][tc+s-1] = t;

//覆盖其余方格

chessBoard(tr+s,tc,tr+s,tc+s-1,s);

}

//覆盖右下角子棋盘

if (dr >= tr + s && dc >= tc + s)

{

//特殊方格在此棋盘中

chessBoard(tr+s,tc+s,dr,dc,s);

}

else

{

//用t号L型骨牌覆盖左上角

Matrix[tr+s][tc+s] = t;

//覆盖其余方格

chessBoard(tr+s,tc+s,tr+s,tc+s,s);

}

}

分治法找到数组中出现次数超过一半的元素

分治法找到数组中出现次数超过一半的元素

#include<stdio.h>

int findCandidate(int arr[],int n){

int candidate=arr[0];

int count=1;

for(int i=1;i<n;i++){

if(arr[i]==candidate){

count++;

}else{

count--;

}

if(count==0){

candidate=arr[i];

count=1;

}

}

return candidate;

}

int findMajorityElement(int arr[],int n){

int candidate=findCandidate(arr,n);

int count=0;

for(int i=0;i<n;i++){

if(arr[i]==candidate){

count++;

}

}

if(count>n/2){

return candidate;

}else{

return -1;

}

}

int main(){

int n;

scanf("%d",&n);

int arr[n];

for(int i=0;i<n;i++){

scanf("%d",&arr[i]);

}

int majorityElement=findMajorityElement(arr,n);

if(majorityElement!=-1){

printf("The majority element in the array:%d\n",majorityElement);

}else{

printf("There is no majority element in the array.\n");

}

return 0;

}

减治法计算数组中的零个数

给定一个整数数组,使用减治法计算数组中的零个数

#include<stdio.h>

#include <limits.h>

int main(int argc ,char const *argv[]){

//请在此处开始编写你的代码

int len;

int zero =0;

scanf("%d",&len);

int arr[len];

for(int i =0;i<len;i++){

scanf("%d",&arr[i]);

}

for(int i=0;i<len;i++){

if(arr[i]==0){

zero++;

}

}

printf("%d",zero);

return 0;

}

分治法计算数组中的负数个数

给定一个整数数组,使用分治法计算数组中的负数个数

#include <stdio.h>

int main(int argc, char const *argv[]) {

int len;

int fu = 0;

scanf("%d", &len);

int arr[len];

for (int i = 0; i < len; i++) {

scanf("%d", &arr[i]);

}

for (int i = 0; i < len; i++) {

if (arr[i] < 0) {

fu++;

}

}

printf("The number of negative elements in the array is:%d", fu);

return 0;

}

减治法计算数组中的正数个数

给定一个整数数组,使用减治法计算数组中的正数个数

#include<stdio.h>

#include <limits.h>

int countPositive(int arr[],int n)

{

if(n==0){

return 0;

}else{

if(arr[n-1]>0){

return 1+countPositive(arr,n-1);

}else{

return countPositive(arr,n-1);

}

}

}

int main(){

int n;

printf("Enter the size of the array:");

scanf("%d",&n);

int arr[n];

printf("Enter the elements of the array:");

for(int i=0;i<n;i++)

{

scanf("%d",&arr[i]);

}

int count = countPositive(arr,n);

printf("the number of positive elements in the array is:%d\n",count);

return 0;

//请在此处开始编写你的代码

}

分治法计算数组中的奇数个数

给定一个整数数组,使用分治法计算该数组中奇数的个数。

#include <limits.h>

#include <stdio.h>

int countOdd(int arr[], int low, int high) {

if (low > high) {

return 0;

} else if (low == high) {

return arr[low] % 2 != 0 ? 1 : 0;

} else {

int mid = (low + high) / 2;

int leftCount = countOdd(arr, low, mid);

int rightCount = countOdd(arr, mid + 1, high);

return leftCount + rightCount;

}

}

int main() {

int n;

printf("Enter the size of the array: ");

scanf("%d", &n);

int arr[n];

printf("Enter the elements of the array: ");

for (int i = 0; i < n; i++) {

scanf("%d", &arr[i]);

}

int count = countOdd(arr, 0, n - 1);

printf("The number of odd elements in the array is: %d\n", count);

return 0;

}

减治法计算数组中的偶数个数

给定一个整数数组,使用减治法计算该数组中偶数的个数。

要求:

1.实现一个函数 int countEven(int arr[], int size),其中 arr 是整数数组,size 是数组的大小。

2.使用减治法思想,在每一步将问题规模减小,直到得到基本问题的解。

3.返回数组中偶数的个数。

#include<stdio.h>

int countEven(int arr[],int n){

if(n==0){

return 0;

}else{

if(arr[n-1]%2==0){

return 1+countEven(arr,n-1);

}else{

return countEven(arr,n-1);

}

}

}

int main(){

int n;

printf("Enter the size of the array:");

scanf("%d",&n);

int arr[n];

printf("Enter the element of the array:");

for(int i=0;i<n;i++){

scanf("%d",&arr[i]);

}

int count=countEven(arr,n);

printf("The number of even elements in the array is:%d\n",count);

return 0;

}

减治法求数组的平均值

给定一个整数数组,用减治法求数组的平均值

#include <stdio.h>

#include <limits.h>

int main(int argc, char const *argv[]) {

//请在此处开始编写你的代码

int len;

int sum = 0;

scanf("%d", &len);

int arr[len];

for (int i = 0; i < len; i++) {

scanf("%d", &arr[i]);

}

for (int i = 0; i < len; i++) {

sum += arr[i];

}

double aver = sum * 1.0 / len;

printf("%.2f", aver);

return 0;

}

与对应负数同时存在的最大正整数

给定一个包含正整数和负整数的数组,找出数组中与每个负数对应的最大正整数,并返回这些最大正整数的和。要求使用分治法或减治法来解决此问题。

#include <stdio.h>

// 获取数组中与负数对应的最大正整数

int getMaxPositive(int nums[], int left, int right) {

// 如果数组为空,返回 0

if (left > right) return 0;

// 如果数组中只有一个元素,且为正数,则返回该正数;否则返回 0

if (left == right) {

if (nums[left] > 0) return nums[left];

else return 0;

}

// 计算数组中间元素的索引

int mid = left + (right - left) / 2;

// 递归求解左右子数组的最大正整数

int leftMax = getMaxPositive(nums, left, mid);

int rightMax = getMaxPositive(nums, mid + 1, right);

// 计算跨越中间元素的最大正整数

int crossMax = 0;

int sum = 0;

for (int i = mid; i >= left; i--) {

sum += nums[i];

if (sum > crossMax) crossMax = sum;

}

sum = 0;

for (int i = mid + 1; i <= right; i++) {

sum += nums[i];

if (sum > crossMax) crossMax = sum;

}

// 返回三者中的最大值

return (leftMax > rightMax) ? ((leftMax > crossMax) ? leftMax : crossMax) : ((rightMax > crossMax) ? rightMax : crossMax);

}

int main() {

int nums[] = {1, -2, 3, -4, 5};

int size = sizeof(nums) / sizeof(nums[0]);

// 计算与负数对应的最大正整数的和

int maxPositiveSum = 0;

for (int i = 0; i < size; i++) {

if (nums[i] < 0) {

maxPositiveSum += getMaxPositive(nums, i + 1, size - 1);

}

}

printf("与对应负数同时存在的最大正整数的和为:%d\n", maxPositiveSum);

return 0;

}

数组元素与数字和的绝对差

给定一个整数数组和一个目标值,找出数组中所有元素与目标值的绝对差最小的元素,并输出它们的绝对差值。

#include<stdio.h>

#include<stdlib.h>

#include <limits.h>

typedef struct{

int value;

int abs_diff;

}Element;

int compare(const void *a,const void *b)

{

return((Element*)a)->abs_diff-((Element*)b)->abs_diff;

}

void findClosestElements(int arr[],int n,int target){

Element elements[n];

for(int i=0;i<n;i++)

{

elements[i].value=arr[i];

elements[i].abs_diff=abs(arr[i]-target);

}

qsort(elements,n,sizeof(Element),compare);

printf("与目标值的绝对差最小的元素为:\n");

for(int i=0;i<n;i++)

{

if(elements[i].abs_diff==elements[0].abs_diff){

printf("%d(数组中与目标值的绝对差最小的元素的绝对差值:%d)\n",elements[i].value,elements[i].abs_diff);

}else{

break;

}

}

}

int main(){

int n;

printf("请输入数字的大小:");

scanf("%d",&n);

int arr[n];

printf("请输入数组元素:");

for(int i=0;i<n;i++)

{

scanf("%d",&arr[i]);}

int target;

printf("请输入目标值:");

scanf("%d",&target);

findClosestElements(arr,n,target);

return 0;

//请在此处开始编写你的代码

}

最小高度树

给定一个已排序(升序)的整数数组,构建一棵高度最小的二叉搜索树(BST)。高度最小的定义是树中任意节点到根节点的距离最小。编写一个程序,在给定的整数数组中构建高度最小的二叉搜索树,并返回根节点。

#include <limits.h>

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

// 二叉树节点结构

struct TreeNode {

int val;

struct TreeNode *left;

struct TreeNode *right;

};

// 构建高度最小的二叉搜索树

struct TreeNode* sortedArrayToBST(int* nums, int start, int end) {

// 边界情况处理

if (start > end) return NULL;

// 找到中间元素的索引

int mid = start + (end - start) / 2;

// 创建当前节点,并赋值

struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));

root->val = nums[mid];

// 递归构建左子树

root->left = sortedArrayToBST(nums, start, mid - 1);

// 递归构建右子树

root->right = sortedArrayToBST(nums, mid + 1, end);

return root;

}

// 中序遍历打印二叉树

void inorderTraversal(struct TreeNode* root) {

if (root) {

inorderTraversal(root->left);

printf("%d ", root->val);

inorderTraversal(root->right);

}

}

int main() {

int nums[] = {-10, -3, 0, 5, 9};

int numsSize = sizeof(nums) / sizeof(nums[0]);

// 构建高度最小的二叉搜索树

struct TreeNode* root = sortedArrayToBST(nums, 0, numsSize - 1);

// 打印构建的二叉搜索树

printf("构建的高度最小的二叉搜索树:");

inorderTraversal(root);

printf("\n");

return 0;

}

减治法实验怎么利用小车才能让两人尽快到达

两人A和B要从城市的起点到终点,城市中有一条笔直的道路,两边有沙漠地带无法行走。他们有一辆小车,但小车只能容纳一人。为了尽快到达目的地,他们决定采用减治法的策略:一人驾驶小车前进,另一人留在原地等待。当小车到达终点后,留在原地的人会驾驶小车返回,再接另一个人继续前进,直到两人都到达终点。编写一个程序,根据两人的起点和终点位置,以及小车的速度,计算两人最快到达终点的时间。

#include<stdio.h>

float fastestTime(int startA,int startB,int endA,int endB,int speedCar){

int distanceToAEnd=endA-startA;

int distanceToBEnd=endB-startB;

float timeToAEnd=(float)distanceToAEnd/speedCar;

float timeToBEnd=(float)distanceToBEnd/speedCar;

return timeToAEnd>timeToBEnd?timeToAEnd:timeToBEnd;

}

int main(){

int startA,startB,endA,endB,speedCar;

printf("请输入A的起点位置:");

scanf("%d",&startA);

printf("请输入B的起点位置:");

scanf("%d",&startB);

printf("请输入A终点位置:");

scanf("%d",&endA);

printf("请输入B的终点位置:");

scanf("%d",&endB);

printf("请输入小车的速度:");

scanf("%d",&speedCar);

float time=fastestTime(startA,startB,endA,endB,speedCar);

printf("最快到达终点的时间:%.1f 小时\n",time);

return 0;

}

减治算法实现8枚硬币问题

给定8枚硬币,其中7枚重量相等,1枚重量稍微不同。要求使用减治算法找出这枚重量不同的硬币,并确定它是轻一些还是重一些。

输入格式:

输入8个正整数,这8个数代表的就是硬币的重量,要求有7个正整数相同,1个不同。

#include <stdio.h>

#include <math.h>

int main() {

int a[8];

int a1, b, numa, numb;

numa = 0;

numb = 0;

for (int i = 0; i < 8; i++) {

scanf("%d", &a[i]);

}

a1 = a[0];

numa++;

for (int i = 1; i < 8; i++) {

if (a[i] == a1) {

numa++;

} else {

b = a[i];

numb++;

}

}

int c;

if (numa < numb) {

c = a1;

} else {

c = b;

}

for (int i = 0; i < 8; i++) {

if (a[i] == c) {

printf("编号:%d  ", i+1);

if (a[i] > a[i - 1]) {

printf("重量:较重");

} else {

printf("重量:较轻");

}

break;

}

}

return 0;

}

使用减治法解决堆排序

堆排序是一种经典的排序算法,基于二叉堆的数据结构。给定一个包含N个整数的数组,现在要求你使用堆排序算法对这个数组进行排序。请编写一个程序,用减治法实现堆排序算法。

输入格式:

1.第一行包含一个整数 N (1 ≤ N ≤ 10^6),表示数组中整数的个数。

2.第二行包含 N 个整数,表示待排序的数组,每个整数的范围为 [-10^9, 10^9]。

#include <limits.h>

//请在此处开始编写你的代码

#include <stdio.h>

// 交换数组中两个元素的位置

void swap(int *a, int *b) {

int temp = *a;

*a = *b;

*b = temp;

}

// 调整堆使得以root为根的子树成为最大堆

void heapify(int arr[], int n, int root) {

int largest = root;  // 初始化根节点为最大值

int left = 2 * root + 1;

int right = 2 * root + 2;

// 如果左子节点比根节点大,则更新最大值的索引

if (left < n && arr[left] > arr[largest]) {

largest = left;

}

// 如果右子节点比根节点大,则更新最大值的索引

if (right < n && arr[right] > arr[largest]) {

largest = right;

}

// 如果最大值不是根节点,则交换并继续调整堆

if (largest != root) {

swap(&arr[root], &arr[largest]);

heapify(arr, n, largest);

}

}

// 堆排序算法

void heapSort(int arr[], int n) {

// 构建最大堆

for (int i = n / 2 - 1; i >= 0; i--) {

heapify(arr, n, i);

}

// 从最后一个非叶子节点开始,依次将最大值与最后一个元素交换并调整堆

for (int i = n - 1; i > 0; i--) {

swap(&arr[0], &arr[i]);  // 将当前最大值放到数组末尾

heapify(arr, i, 0);      // 调整剩余元素使得成为最大堆

}

}

int main() {

int n;

scanf("%d", &n);

int arr[n];

for (int i = 0; i < n; i++) {

scanf("%d", &arr[i]);

}

heapSort(arr, n);

// 输出排好序的数组元素

for (int i = 0; i < n; i++) {

printf("%d ", arr[i]);

}

printf("\n");

return 0;

}

数字旋转方阵

给定一个N × N 的方阵,每个格子里填有一个整数。现在要求你将这个方阵按照顺时针方向旋转90度。请编写一个程序,实现这个旋转操作。

输入格式:

1.第一行包含一个整数 N (1 ≤ N ≤ 100),表示方阵的大小。

2.接下来 N 行,每行包含 N 个整数,表示方阵中每个格子的值,每个整数的范围为 [-1000, 1000]。

//请在此处开始编写你的代码

#include<stdio.h>

#define MAX_SIZE 100

void rotateMatrix(int matrix[MAX_SIZE][MAX_SIZE],int n){

int rotated[MAX_SIZE][MAX_SIZE];

for(int i=0;i<n;i++){

for(int j=0;j<n;j++){

rotated[j][n-1-i]=matrix[i][j];

}

}

for(int i=0;i<n;i++){

for(int j=0;j<n;j++){

matrix[i][j]=rotated[i][j];

}

}

}

int main(){

int n;

int matrix[MAX_SIZE][MAX_SIZE];

scanf("%d",&n);

for(int i=0;i<n;i++){

for(int j=0;j<n;j++){

scanf("%d",&matrix[i][j]);

}

}

rotateMatrix(matrix,n);

for(int i=0;i<n;i++){

for(int j=0;j<n;j++){

printf("%d",matrix[i][j]);

}

printf("\n");

}

return 0;

}

背包问题

有一个背包,容量为 capacity,现有一些物品,每件物品都有自己的重量 weights[i] 和价值 values[i]。需要从这些物品中选择一些放入背包中,使得放入的物品总重量不超过背包的容量,并且使得放入的物品总价值最大化。设计一个程序,求解该背包问题,并输出放入背包的物品及其总价值。

要求:编写一个函数,接受背包容量、物品重量数组和物品价值数组作为输入,并返回最大化的总价值。

输入格式:

一个整数 capacity,表示背包的容量。

物品数量

一个整数数组 weights[],表示每件物品的重量。

一个整数数组 values[],表示每件物品的价值。

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

// 返回两个整数中的较大值

int max(int a, int b) {

return (a > b) ? a : b;

}

// 背包问题的分治法求解函数

int knapsack(int capacity, int weights[], int values[], int n) {

// 如果没有物品或者背包容量为0,则返回0

if (n == 0 || capacity == 0) {

return 0;

}

// 如果当前物品的重量大于背包容量,则跳过该物品

if (weights[n - 1] > capacity) {

return knapsack(capacity, weights, values, n - 1);

}

// 计算包含当前物品和不包含当前物品两种情况下的最大价值

int include = values[n - 1] + knapsack(capacity - weights[n - 1], weights, values, n - 1);

int exclude = knapsack(capacity, weights, values, n - 1);

// 返回两种情况下的最大值

return max(include, exclude);

}

int main() {

int capacity, n;

// 读取背包容量

printf("请输入背包容量:\n");

scanf("%d", &capacity);

// 读取物品数量

printf("请输入物品数量:\n");

scanf("%d", &n);

// 读取物品重量和价值数组

int weights[n], values[n];

printf("请输入物品重量:\n");

for (int i = 0; i < n; i++) {

scanf("%d", &weights[i]);

}

printf("请输入物品价值:\n");

for (int i = 0; i < n; i++) {

scanf("%d", &values[i]);

}

int maxValue = knapsack(capacity, weights, values, n);

printf("最大总价值为:%d\n", maxValue);

return 0;

}

俄式乘法

俄式乘法是一种通过将两个数分别以二进制形式展开,并利用加法和位移运算来实现的乘法方法。该方法的基本思想是将较大的数按位分解为二进制,然后将乘法问题转化为一系列的加法和位移运算。设计一个程序,实现俄式乘法,计算两个给定的正整数的乘积。

要求:编写一个函数,接受两个正整数作为输入,并使用俄式乘法算法来计算它们的乘积。

#include<stdio.h>

#include<math.h>

int getNumDigits(int num){

return(num==0)?1:(int)(log10(num)+1);

}

int russianMultiplication(int a,int b,int digits){

if(a==0||b==0){

return 0;

}

if(digits==1){

return a*b;

}

int a_high=a/(int)pow(10,digits/2);

int a_low=a%(int)pow(10,digits/2);

int b_high=b/(int)pow(10,digits/2);

int b_low=b%(int)pow(10,digits/2);

int p1=russianMultiplication(a_high,b_high,digits/2);

int p2=russianMultiplication(a_high,b_low,digits/2);

int p3=russianMultiplication(a_low,b_high,digits/2);

int p4=russianMultiplication(a_low,b_low,digits/2);

return p1*(int)pow(10,digits)+(p2+p3)*(int)pow(10,digits/2)+p4;

}

int main(){

int a;

int b;

printf("请输入两个正整数:\n");

scanf("%d %d",&a,&b);

int digits=getNumDigits(a>b?a:b);

int product=russianMultiplication(a,b,digits);

printf("俄式乘法:%d*%d=%d\n",a,b,product);

return 0;

}

淘汰冠军问题

有 n 个选手参加一场比赛,每个选手都有一个唯一的正整数编号,并且比赛结果已经确定。现在,你需要设计一个程序来找出淘汰冠军。淘汰冠军的规则如下:选手依次排成一列,第一轮比赛时,第一个选手与第二个选手比赛,第三个选手与第四个选手比赛,以此类推。在每一轮中,编号较大的选手将被淘汰,而编号较小的选手将进入下一轮。如果参加比赛的选手数为奇数,则最后一个选手将直接晋级下一轮。重复以上步骤,直到只剩下一个选手,该选手即为冠军。要求:编写一个函数,接受一个整数数组作为输入,数组中存储了每个选手的编号,并找出淘汰冠军的编号。

#include<stdio.h>

#include <limits.h>

//请在此处开始编写你的代码

// 找出淘汰冠军的函数

int findChampion(int arr[], int n) {

// 当只剩下一个选手时,该选手为冠军

if (n == 1) {

return arr[0];

}

// 用于存储下一轮的选手编号

int nextRound[n / 2];

int j = 0;

// 进行当前轮比赛

for (int i = 0; i < n; i += 2) {

// 当还有两个选手时,较小的选手晋级下一轮

if (i == n - 1) {

nextRound[j] = arr[i];

break;

}

// 较小的选手晋级下一轮

if (arr[i] < arr[i + 1]) {

nextRound[j] = arr[i];

} else {

nextRound[j] = arr[i + 1];

}

j++;

}

// 递归调用,进入下一轮比赛

return findChampion(nextRound, n / 2);

}

int main() {

int n;

printf("Enter the number of players: ");

scanf("%d", &n);

int arr[n];

printf("Enter the player IDs: ");

for (int i = 0; i < n; i++) {

scanf("%d", &arr[i]);

}

int champion = findChampion(arr, n);

printf("淘汰冠军的编号: %d\n", champion);

return 0;

}

减治法求a的n次方

设计一个程序,使用减治法来计算an。

输入格式:

第一行输入底数a的值

第二行输入次方数n

#include <stdio.h>

#include <math.h>

double an(int a,int n){

if(n==1) return a;

else{

if(n%2 == 0)

return pow(an(a, n/2),2);

else

return a*pow( an(a,(n-1)/2) , 2);

}

}

int main(){

int a,n;

scanf("%d",&a);

scanf("%d",&n);

int rs=an(a, n);

printf("%d的%d次方结果为:%d",a,n,rs);

}

使用减治法和递归方法实现插入排序算法

设计一个程序,使用减治法和递归方法实现插入排序算法

#include <stdio.h>

void inserSort(int a[], int n) {

int key = a[n], i;

for(i = n - 1; i >= 0; i--) {

if(a[i] > key) a[i + 1] = a[i];

else break;

}

a[i + 1] = key;

}

void insertionSortRecur(int a[], int n) { //n表示元素的个数

if(n <= 1) return;

insertionSortRecur(a, n - 1); //减小规模

inserSort(a, n - 1);

}

int main() {

int n,a[n];

scanf("%d",&n);

for(int i = 0; i < n; i++) {

scanf("%d ", &a[i]);

}

insertionSortRecur(a, n);

printf("Sorted array: [");

for(int i = 0; i < n; i++) {

printf("%d", a[i]);

if(i != n-1)

{

printf(",");

}

else

{

printf("]");

}

}

return 0;

}

矢量点乘

设计一个程序,实现两个n维向量的点乘运算。向量点乘是指将两个向量中对应位置的元素相乘,并将结果相加得到一个标量值的运算。

#include <limits.h>

//请在此处开始编写你的代码

#include <stdio.h>

#define N 3

// 计算两个矢量的点乘

int dotProduct(int vec1[], int vec2[]) {

int result = 0;

for (int i = 0; i < N; i++) {

result += vec1[i] * vec2[i];

}

return result;

}

int main() {

int vec1[N], vec2[N];

printf("Enter the elements of the first vector: ");

for (int i = 0; i < N; i++) {

scanf("%d", &vec1[i]);

}

printf("Enter the elements of the second vector: ");

for (int i = 0; i < N; i++) {

scanf("%d", &vec2[i]);

}

int result = dotProduct(vec1, vec2);

printf("The dot product of the two vectors is: %d\n", result);

return 0;

}

分治法求数组中相差最小的两个元素(最接近数)的差

给定一个整数数组,编写一个程序来找到数组中相差最小的两个元素,并计算它们之间的差值。

#include<stdio.h>

#include<stdlib.h>

#include <limits.h>

//比较函数,用于qsort排序

int compare(const void*a,const void*b){

return(*(int*)a-*(int*)b);

}

//求两个数的差

int findMinDiff(int arr[],int n){

if(n<2){

return -1;//数组元素个数小于2,无法求解

}

//先对数组进行排序

qsort(arr,n,sizeof(int),compare);

//初始化最小差值可能为最大值

int minDiff=INT_MAX;

//求相邻两个元素之差的最小值

for(int i=1;i<n;i++){

if(arr[i]-arr[i-1]<minDiff){

minDiff=arr[i]-arr[i-1];

}

}

return minDiff;

}

int main(){

int n;

printf("Enter the number of elements in the array:");

scanf("%d",&n);

int arr[n];

printf("Enter the elements of the array:");

for(int i=0;i<n;i++){

scanf("%d",&arr[i]);

}

int result=findMinDiff(arr,n);

if(result==-1){

printf("Array must have at least 2 elements.\n");

}else{

printf("The minimum difference between two elements is:%d\n",result);

}

return 0;

}

分治法对任意的n值构造相应的格雷码

格雷码是一个长度为2n的序列,序列中无相同元素,且每个元素都是长度为n的二进制位串,相邻元素恰好只有1位不同。例如长度为23的格雷码为(000,001,011,010,110,111,101,100)。设计分治算法对任意的n值构造相应的格雷码。

#include <math.h>

#include <stdio.h>

int a[10000][10000];

//求num个n位Gray码

void GrayCode(int n, int num);

int main() {

int n; //输入Gray码位数n

scanf("%d", &n) ;

//n位Gray码的个数num

int num = (int)pow(2.0, n);

//求num个n位Gray码

GrayCode(n, num);

//输出num个n位Gray码

//为了方便运算,Gray码的矩阵从左上角开始构建,最高位在最右边,输出时每个Gray码从右往左输出

printf("Gray code sequence for n=%d\n",n);

for (int i = 0; i < num; ++i) {

for (int j = n - 1; j >= 0; --j) {

printf("%d", a[i][j]);

}

printf("\n");

}

return 0;

}

void GrayCode(int n, int num) {

//分治到只有1位Gray码的情况

if (n == 1) {

a[0][0] = 0;

a[1][0] = 1;

return;

}

//将求解n位Gray码的问题划分成求解n-1位Gray码的问题

GrayCode(n - 1, num / 2);

//n位Gray码的前半部分最高位置0,其余位不变

for (int i = 0; i < num / 2; ++i) {

a[i][n - 1] = 0;

}

//n位Gray码的后半部分最高位置1,其余位由n-1位Gray码翻转而来

for (int i = num / 2; i < num; ++i) {

a[i][n - 1] = 1;

for (int j = 0; j < n - 1; ++j) {

a[i][j] = a[num - i - 1][j];

}

}

}

使用分治法解决铺地毯问题

某个房间的地面被分割成一个个方格,每个方格被编号为 (x, y),其中 x 和 y 分别表示该方格的横纵坐标。现在有一些地毯需要铺在这个房间的地面上,每块地毯被描述为一个矩形,左下角坐标为 (x1, y1),右上角坐标为 (x2, y2)。如果一块地毯覆盖了一个方格,那么该方格就会被视为被覆盖。请设计一个算法,利用分治法判断给定的一个点 (x, y) 是否被地毯覆盖。

1.将地毯问题划分为多个子问题,每个子问题为判断点 (x, y) 是否被一个地毯覆盖。

2.对于每块地毯,判断点 (x, y) 是否位于其覆盖范围内。

//请在此处开始编写你的代码

#include <stdio.h>

// 定义地毯结构体

struct Carpet {

int x1, y1; // 左下角坐标

int x2, y2; // 右上角坐标

};

// 判断点是否在矩形范围内

int isInside(struct Carpet c, int x, int y) {

return (x >= c.x1 && x <= c.x2 && y >= c.y1 && y <= c.y2);

}

// 判断给定点是否被地毯覆盖

int isCovered(struct Carpet carpets[], int n, int x, int y) {

// 遍历每块地毯

for (int i = 0; i < n; i++) {

// 如果点在当前地毯的范围内,则返回当前地毯的编号

if (isInside(carpets[i], x, y)) {

return i;

}

}

// 如果点不被任何地毯覆盖,则返回-1

return -1;

}

int main() {

// 地毯数量

int n;

printf("Enter the number of carpets: ");

scanf("%d", &n);

// 输入每块地毯的信息

struct Carpet carpets[n];

for (int i = 0; i < n; i++) {

printf("Enter the coordinates of carpet %d (x1 y1 x2 y2): ", i + 1);

scanf("%d %d %d %d", &carpets[i].x1, &carpets[i].y1, &carpets[i].x2, &carpets[i].y2);

}

// 输入需要判断的点的坐标

int x, y;

printf("Enter the coordinates of the point (x y): ");

scanf("%d %d", &x, &y);

// 判断给定点是否被地毯覆盖

int covered = isCovered(carpets, n, x, y);

if (covered != -1) {

printf("The point (%d, %d) is covered by carpet %d.\n", x, y, covered + 1);

} else {

printf("The point (%d, %d) is not covered by any carpet.\n", x, y);

}

return 0;

}

使用减治法找数组中第K大元素

给定一个包含不同整数的无序数组,以及一个整数k。请设计一个算法,利用减治法找出数组中第k大的元素。

#include <stdio.h>

int partition(int arr[], int low, int high) {

int pivot = arr[high];

int i = low - 1;

for (int j = low; j < high; j++) {

if (arr[j] > pivot) {

i++;

int temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

}

}

int temp = arr[i + 1];

arr[i + 1] = arr[high];

arr[high] = temp;

return i + 1;

}

int quickSelect(int arr[], int low, int high, int k) {

if (low <= high) {

int pivot = partition(arr, low, high);

if (pivot == k - 1) {

return arr[pivot];

} else if (pivot < k - 1) {

return quickSelect(arr, pivot + 1, high, k);

} else {

return quickSelect(arr, low, pivot - 1, k);

}

}

return -1; // Error case

}

int main() {

int arr[] = {3, 9, 4, 5, 1, 8, 2, 7};

int n = sizeof(arr) / sizeof(arr[0]);

int k = 2; // Find the 2nd largest element

int result = quickSelect(arr, 0, n - 1, k);

if (result != -1) {

printf("The %d-th largest element is: %d\n", k, result);

} else {

printf("Invalid input\n");

}

return 0;

}

使用减治法求斐波那契数列的第n项

给定斐波那契数列的定义F(0)=0,F(1)=1,对于n>=2,F(n)=F(n-1)+F(n-2).请设计一个算法,利用减治法求解斐波那契数列的第n项

#include <stdio.h>

int F(int n) {

if (n == 0) {

return 0;

} else if (n == 1) {

return 1;

} else if (n >= 2) {

return F(n - 1) + F(n - 2);

}

}

int main() {

int n;

scanf("%d", &n);

int a = F(n);

printf("The %d-th Fibonacci number is:%d\n", n, a);

return 0;

}

使用减治法找到整数数组元素之和

使用减治法找到整数数组元素之和

#include <stdio.h>

int main() {

int n;

scanf("%d", &n);

int a[n];

for (int i = 0; i < n; i++) {

scanf("%d", &a[i]);

}

int sum = 0;

for (int i = 0; i < n; i++) {

sum += a[i];

}

printf("%d", sum);

return 0;

}

求点到线段所在直线垂线的垂足

编写一段C语言算法,要求点到线段所在直线垂线的垂足

要计算一个点到线段所在直线的垂足,我们可以使用向量运算。首先,我们计算线段两个端点构成的向量,然后计算点到线段一个端点的向量。通过这两个向量,我们可以得到垂线的方向向量(即这两个向量的叉积)。然后,我们可以利用点积来计算垂足的位置。

//请在此处开始编写你的代码

#include <stdio.h>  

#include <math.h>  

typedef struct {  

double x;  

double y;  

} Point;  

Point perpendicularFoot(Point A, Point B, Point P) {  

double ABx = B.x - A.x;  

double ABy = B.y - A.y;  

double APx = P.x - A.x;  

double APy = P.y - A.y;  

// 计算点A到点P的向量与线段AB的向量的点积  

double dot = ABx * APx + ABy * APy;  

// 计算线段AB的向量的模长的平方  

double ABsq = ABx * ABx + ABy * ABy;  

// 防止除以0的情况  

if (fabs(ABsq) < 1e-9) {  

return A; // 如果AB几乎为0,那么垂足就是A  

}  

// 计算参数t,表示点P到垂足的距离与点A到垂足的距离的比例  

double t = dot / ABsq;  

// 计算垂足的坐标  

Point foot;  

foot.x = A.x + t * ABx;  

foot.y = A.y + t * ABy;  

return foot;  

}  

int main() {  

Point A, B, P;  

printf("请输入点A的坐标(x y):");  

scanf("%lf %lf", &A.x, &A.y);  

printf("请输入点B的坐标(x y):");  

scanf("%lf %lf", &B.x, &B.y);  

printf("请输入点P的坐标(x y):");  

scanf("%lf %lf", &P.x, &P.y);  

Point foot = perpendicularFoot(A, B, P);  

printf("垂足的坐标为: (%f, %f)\n", foot.x, foot.y);  

return 0;  

}

求矢量夹角

请编写一段C程序代码,要求计算两矢量之间的夹角

计算流程如下:

由点乘求夹角,再判断正负向量点乘求夹角:

a * b= |a| * |b| * cos<a,b>=a.x * b.x + a.y* b.y

所以<a,b> = acos((a * b)/ ( |a| * |b|) );

结果为正值,需要判定正负,来确定角方向;

由向量叉乘判断正负:

a X b = |a| * |b| * sin<a,b>=a.x * b.y - a.y * b.x;

如果aXb < 0,那么 <a,b> = -<a,b>

//请在此处开始编写你的代码

#include <stdio.h>  

#include <math.h>  

typedef struct {  

double x;  

double y;  

} Vector;  

double dotProduct(Vector v1, Vector v2) {  

return v1.x * v2.x + v1.y * v2.y;  

}  

double magnitude(Vector v) {  

return sqrt(v.x * v.x + v.y * v.y);  

}  

double angleBetweenVectors(Vector v1, Vector v2) {  

double dot = dotProduct(v1, v2);  

double mag1 = magnitude(v1);  

double mag2 = magnitude(v2);  

// 计算夹角的余弦值  

double cosTheta = dot / (mag1 * mag2);  

// 计算夹角(弧度)  

double thetaRad = acos(cosTheta);  

// 将弧度转换为度  

double thetaDeg = thetaRad * (180.0 / M_PI);  

return thetaDeg;  

}

int main() {  

Vector v1, v2;  

printf("请输入第一个矢量的x坐标和y坐标(用空格分隔):");  

scanf("%lf %lf", &v1.x, &v1.y);  

printf("请输入第二个矢量的x坐标和y坐标(用空格分隔):");  

scanf("%lf %lf", &v2.x, &v2.y);  

double angle = angleBetweenVectors(v1, v2);  

printf("两个矢量的夹角为:%.2lf度\n", angle);  

return 0;  

}

求一点饶某点旋转后的坐标

要求编写一段C语言程序,实现 A 点绕 B 点旋转 n 角度后的 A 点坐标

//请在此处开始编写你的代码

#include <stdio.h>

#include <math.h>

// 定义一个结构体来存储点的坐标

typedef struct {

double x;

double y;

} Point;

// 函数用于将角度转换为弧度

double degreesToRadians(double degrees) {

return degrees * M_PI / 180.0;

}

// 函数用于计算点绕原点的旋转

Point rotateAroundOrigin(Point point, double angleRadians) {

double cosTheta = cos(angleRadians);

double sinTheta = sin(angleRadians);

Point rotatedPoint;

rotatedPoint.x = point.x * cosTheta - point.y * sinTheta;

rotatedPoint.y = point.x * sinTheta + point.y * cosTheta;

return rotatedPoint;

}

// 函数用于计算点绕任意点的旋转

Point rotateAroundPoint(Point point, Point center, double angleRadians) {

// 先将点平移到原点

Point shiftedPoint = { point.x - center.x, point.y - center.y };

// 绕原点旋转

Point rotatedPoint = rotateAroundOrigin(shiftedPoint, angleRadians);

// 将旋转后的点平移回原来的位置

rotatedPoint.x += center.x;

rotatedPoint.y += center.y;

return rotatedPoint;

}

int main() {

Point A, B;

double angleDegrees;

// 读取输入

scanf("%lf %lf", &A.x, &A.y);

scanf("%lf %lf", &B.x, &B.y);

scanf("%lf", &angleDegrees);

// 计算旋转后的坐标

double angleRadians = degreesToRadians(angleDegrees);

Point rotatedA = rotateAroundPoint(A, B, angleRadians);

// 输出结果

printf("旋转后的坐标是: (%.2f, %.2f)\n", rotatedA.x, rotatedA.y);

return 0;

}

判断点是否在线段上

请编写一段c语言代码,要求判断一个点是否在线段AB上(要求手动输入数据)

//请在此处开始编写你的代码

#include <stdio.h>

// 定义点的结构体

typedef struct {

int x;

int y;

} Point;

// 判断点P是否在线段AB上

int isOnSegment(Point A, Point B, Point P) {

// 计算向量AB和向量AP的叉积

int cross = (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x);

// 如果叉积为0且P在A和B之间,则点P在线段AB上

if (cross == 0 && (P.x >= A.x && P.x <= B.x) && (P.y >= A.y && P.y <= B.y)) {

return 1;

} else {

return 0;

}

}

int main() {

Point A, B, P;

// 输入线段端点A的坐标

scanf("%d %d", &A.x, &A.y);

// 输入线段端点B的坐标

scanf("%d %d", &B.x, &B.y);

// 输入要判断的点P的坐标

scanf("%d %d", &P.x, &P.y);

// 调用函数判断点P是否在线段AB上

if (isOnSegment(A, B, P)) {

printf("点P在线段AB上\n");

} else {

printf("点P不在线段AB上\n");

}

return 0;

}

矢量叉乘

矢量叉乘的计算主要基于叉乘的定义和性质。对于两个三维向量A和B,它们的叉乘结果是一个新的向量C,其方向垂直于A和B所在的平面,并且遵循右手螺旋定则。向量C的模长等于A和B构成的平行四边形的面积。

//请在此处开始编写你的代码

#include <stdio.h>

// 定义一个结构体来存储三维向量的分量

typedef struct {

double x;

double y;

double z;

} Vector3D;

// 函数用于计算两个三维向量的叉乘

Vector3D crossProduct(Vector3D A, Vector3D B) {

Vector3D C;

C.x = A.y * B.z - A.z * B.y;

C.y = A.z * B.x - A.x * B.z;

C.z = A.x * B.y - A.y * B.x;

return C;

}

int main() {

Vector3D A, B, C;

// 读取向量A的分量

scanf("%lf", &A.x);

scanf("%lf", &A.y);

scanf("%lf", &A.z);

// 读取向量B的分量

scanf("%lf", &B.x);

scanf("%lf", &B.y);

scanf("%lf", &B.z);

// 计算叉乘结果

C = crossProduct(A, B);

// 输出结果

printf("叉乘结果向量为:(%f,%f,%f)", C.x, C.y, C.z);

return 0;

}

判断平面两点是否重合

请编写一个算法,用以判断平面上的两点是否重合

//请在此处开始编写你的代码

#include <stdio.h>

int main() {

int x1, y1, x2, y2;

// 读取输入

scanf("%d", &x1);

scanf("%d", &y1);

scanf("%d", &x2);

scanf("%d", &y2);

// 判断两点是否重合

if (x1 == x2 && y1 == y2) {

printf("The two points are equal.\n");

} else {

printf("The two points are not equal.\n");

}

return 0;

}

计算平面两点距离

在平面上,两点之间的距离可以通过欧几里得距离公式来计算。对于两点 A(x1, y1) 和 B(x2, y2),它们之间的距离 d 可以用以下公式表示:

d = sqrt((x2 - x1)² + (y2 - y1)²)

#include <stdio.h>

#include <math.h>

int main() {

int x1, y1, x2, y2;

scanf("%d", &x1);

scanf("%d", &y1);

scanf("%d", &x2);

scanf("%d", &y2);

double d;

d = sqrt((x2 - x1) * (x2 - x1) * 1.0 + (y2 - y1) * (y2 - y1) * 1.0);

printf("The distance between the two points is:%lf", d);

return 0;

}

汉诺塔

//请在此处开始编写你的代码

#include <stdio.h>

// 函数原型声明

void hanoi(int n, char source, char auxiliary, char target);

int main() {

int n;

// 读取输入

scanf("%d", &n);

// 调用汉诺塔函数

hanoi(n, 'A', 'B', 'C');

return 0;

}

// hanoi函数实现

void hanoi(int n, char source, char auxiliary, char target) {

if (n == 1) {

// 只有一个圆盘,直接移动到目标杆

printf("Move disk %d from %c to %c\n", n, source, target);

} else {

// 递归步骤1:将n-1个圆盘从source移动到auxiliary

hanoi(n - 1, source, target, auxiliary);

// 打印移动n的圆盘

printf("Move disk %d from %c to %c\n", n, source, target);

// 递归步骤2:将n-1个圆盘从auxiliary移动到target

hanoi(n - 1, auxiliary, source, target);

}

}

对链表排序

创建一个无序链表,使用算法对其排序,使其变为升序链表

#include <stdio.h>

#include <stdlib.h>

// 定义链表节点结构体

typedef struct ListNode {

int val; struct ListNode *next;

} ListNode;

// 创建新节点

ListNode *createNode(int val) {

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));

if (!newNode) {

perror("Memory allocation failed");

exit(EXIT_FAILURE);

}

newNode->val = val;

newNode->next = NULL;

return newNode;

}

// 插入节点到链表尾部

void insertNode(ListNode **head, int val) {

ListNode *newNode = createNode(val);

if (*head == NULL) {

*head = newNode;

} else {

ListNode *temp = *head;

while (temp->next != NULL) {

temp = temp->next;

}

temp->next = newNode;

}

}

// 打印链表

void printList(ListNode *head) {

ListNode *temp = head;

while (temp != NULL) {

printf("%d ", temp->val);

temp = temp->next;

}

printf("\n");

}

// 排序链表

void sortList(ListNode **head) {

if (head == NULL || *head == NULL) {

return;

}

ListNode *sorted = NULL;

ListNode *current = *head;

ListNode *temp = NULL;

// 遍历链表,将每个节点插入到排序链表中

while (current != NULL) {

// 先暂时从原链表中移除当前节点

temp = current->next;

current->next = NULL;

// 如果排序链表为空或者当前节点值小于排序链表最后一个节点的值,则直接插入

if (sorted == NULL || current->val < sorted->val) {

current->next = sorted;

sorted = current;

} else {

ListNode *cur = sorted;

while (cur->next != NULL && cur->next->val < current->val) {

cur = cur->next;

}

current->next = cur->next;

cur->next = current;

}

// 继续处理下一个节点

current = temp;

}

// 更新头指针指向排序后的链表

*head = sorted;

}

int main() {

ListNode *head = NULL;

int val;

// 读取输入并创建链表

while (scanf("%d", &val) && val != -1) {

insertNode(&head, val);

}

// 打印原始链表

printf("原始链表: ");

printList(head);

// 排序链表

sortList(&head);

// 打印排序后的链表

printf("排序后的链表: ");

printList(head);

// 释放链表内存

ListNode *temp;

while (head != NULL) {

temp = head;

head = head->next;

free(temp);

}

return 0;

}

合并两个升序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

typedef struct Node {

int data;

struct Node *next;

} Node;

Node *createNode(int data) {

Node *newNode = (Node *)malloc(sizeof(Node));

newNode->data = data;

newNode->next = NULL;

return newNode;

}

void insertNode(Node **head, int data) {

Node *newNode = createNode(data);

if (*head == NULL || (*head)->data >= newNode->data) {

newNode->next = *head;

*head = newNode;

} else {

Node *current = *head;

while (current->next != NULL && current->next->data < newNode->data) {

current = current->next;

}

newNode->next = current->next;

current->next = newNode;

}

}

void printList(Node *head) {

while (head != NULL) {

printf("%d ", head->data);

head = head->next;

}

printf("\n");

}

Node *mergeLists(Node *first, Node *second) {

Node dummy;

dummy.next = NULL;

Node *tail = &dummy;

while (first != NULL && second != NULL) {

if (first->data < second->data) {

tail->next = first;

first = first->next;

} else {

tail->next = second;

second = second->next;

}

tail = tail->next;

}

tail->next = first ? first : second;

return dummy.next;

}

int main() {

Node *list1 = NULL;

Node *list2 = NULL;

int data;

// 读取第一个链表的值

printf("输入第一个有序链表的值(以-1结束):\n");

scanf("%d", &data);

while (data != -1) {

insertNode(&list1, data);

scanf("%d", &data);

}

// 读取第二个链表的值

printf("输入第二个有序链表的值(以-1结束):\n");

scanf("%d", &data);

while (data != -1) {

insertNode(&list2, data);

scanf("%d", &data);

}

// 打印原始链表

printf("List 1: ");

printList(list1);

printf("List 2: ");

printList(list2);

// 合并链表

Node *mergedList = mergeLists(list1, list2);

// 打印合并后的链表

printf("Merged List: ");

printList(mergedList);

// 释放链表内存

while (mergedList != NULL) {

Node *temp = mergedList;

mergedList = mergedList->next;

free(temp);

}

return 0;

}

二分搜索

二分搜索,也称折半搜索或对数搜索,是一种在有序数组中查找某一特定元素的搜索算法。该算法的基本思想是每次都将搜索范围缩小一半,直到找到目标元素或搜索区间为空为止。

//请在此处开始编写你的代码

#include <stdio.h>

// 二分搜索函数

int binarySearch(int arr[], int l, int r, int x) {

while (l <= r) {

int m = l + (r - l) / 2;

// 检查m是否是x的索引

if (arr[m] == x) {

return m;

}

// 如果x更大,我们对右侧子数组进行搜索

if (arr[m] < x) {

l = m + 1;

}

// 如果x更小,我们对左侧子数组进行搜索

else {

r = m - 1;

}

}

// 如果我们没有找到x,返回-1

return -1;

}

int main() {

int n, target, result;

scanf("%d", &n); // 读取数列的元素个数

int arr[n];

scanf("%d", &arr[0]); // 读取第一个元素并开始构建数组

for (int i = 1; i < n; i++) {

scanf("%d", &arr[i]);

}

scanf("%d", &target); // 读取要搜索的目标值

// 调用二分搜索函数

result = binarySearch(arr, 0, n - 1, target);

// 输出结果

if (result != -1) {

printf("元素 %d 在数列中的索引为 %d\n", target, result);

} else {

printf("元素 %d 不在数列中\n", target);

}

return 0;

}

快速排序

//请在此处开始编写你的代码

#include <stdio.h>

// 定义一个结构体来存储快速排序的索引

typedef struct {

int low;

int high;

} Index;

// 交换两个元素的值

void swap(int *a, int *b) {

int temp = *a;

*a = *b;

*b = temp;

}

// 快速排序的分区函数

int partition(int arr[], int low, int high) {

int pivot = arr[high]; // 选择最右侧元素作为基准

int i = low - 1;       // i指针用于记录小于基准的元素的最右位置

for (int j = low; j < high; j++) {

// 如果当前元素小于或等于基准

if (arr[j] <= pivot) {

i++; // i指针右移

swap(&arr[i], &arr[j]);

}

}

// 将基准元素放到正确的位置

swap(&arr[i + 1], &arr[high]);

return i + 1;

}

// 快速排序的递归函数

void quickSort(int arr[], int low, int high) {

if (low < high) {

// 分区并得到基准的索引

int pivotIndex = partition(arr, low, high);

// 对基准左边的子序列进行快速排序

quickSort(arr, low, pivotIndex - 1);

// 对基准右边的子序列进行快速排序

quickSort(arr, pivotIndex + 1, high);

}

}

// 主函数

int main() {

int n, i;

// 读取数列长度

scanf("%d", &n);

int arr[n];

// 读取数列

for (i = 0; i < n; i++) {

scanf("%d", &arr[i]);

}

// 执行快速排序

quickSort(arr, 0, n - 1);

// 输出排序后的数组

printf("Sorted array:\n");

for (i = 0; i < n; i++) {

printf("%d ", arr[i]);

}

printf("\n");

return 0;

}

循环赛日程表问题

循环赛日程表问题,指的是在给定参赛选手数量的情况下,如何安排每两名选手之间的比赛,使得每名选手在相邻的两场比赛中都不会遇到相同的对手。这个问题通常可以通过使用分治策略来解决,特别是当参赛人数数量为偶数时,可以方便地利用分治策略来构造循环赛日程表。

//请在此处开始编写你的代码

#include <stdio.h>

#include<stdlib.h>

#include<string.h>

//分治递归,mStart是分治区域的起始的纵坐标,mEnd是分治区域结束的纵坐标

//nStart是分治区域的起始的横坐标,nEnd是分治区域的结束的横坐标

void arrange(int** a, int mStart, int mEnd, int nStart, int nEnd)

{ //只有一个参赛选手,只能自己与自己比 if (mStart == mEnd && nStart == nEnd)

if(mStart==mEnd&&nStart==nEnd)

{

a[mStart][nStart] = nStart;

return;

}

//有两个选手,矩阵对角线相等

if (mStart + 1 == mEnd && nStart + 1 == nEnd)

{ //主对角线相等

a[mStart][nStart] = nStart;

a[mEnd][nEnd] = nStart;

//逆对角线相等

a[mStart][nEnd] = nEnd;

a[mEnd][nStart] = nEnd;

return;

}

int mMid = (mStart + mEnd) / 2;

int nMid = (nStart + nEnd) / 2;

arrange(a, mStart, mMid, nStart, nMid);//左上角分块矩阵

arrange(a, mStart, mMid, nMid + 1, nEnd);//右上角分块矩阵

//将左上角分块矩阵复制到右下角

for (int i = mMid + 1; i <= mEnd; i++)

{

for (int j = nMid + 1; j <= nEnd; j++)

{

a[i][j] = a[i - mMid][j - nMid];

}

}

//将右上角分块矩阵复制到左下角

for (int i = mMid+1; i <= mEnd; i++)

{

for (int j = nStart; j <= nMid; j++)

{

a[i][j] = a[i - (mMid-mStart+1)][j + (nMid - nStart+1)];//mMid-mStart+1是左下角纵坐标到上半矩阵对应纵坐标的距离,nMid - nStart+1同理

}

}

}

//打印矩阵

void printMatrix(int** a, int m, int n)

{ printf("参赛\n选手\t");

for (int i = 2; i < n; i++)

{ printf("第%d天\t", i - 1); }

printf("\n");

for (int i = 1; i < m; i++)

{

for (int j = 1; j < n; j++)

{

printf("%d\t", a[i][j]);

}

printf("\n");

}

}

int main()

{ int m = 0;//参赛选手人数

printf("请输入参赛选手的个数:\n");

scanf("%d", &m);

if ((m & (m-1)) != 0)//判断2的n次方的经典条件(m & (m-1))的结果为0就是,注意加括号,符号优先级要注意

{ printf("参赛选手必须为2的n次方!\n");

return 0;

}

int** matrix = (int**)malloc((m+1) * sizeof(int*));

for (int i = 0; i < (m+1); i++)

{ matrix[i] = (int*)malloc((m + 1) * sizeof(int));

memset(matrix[i], 0, (m + 1) * sizeof(int));//将二维数组每一行置为0

}

arrange(matrix, 1, m, 1, m);

printMatrix(matrix, m+1, m+1);

}

线性时间选择选k小值

线性时间选择算法(Linear Time Selection Algorithm)是一种能在O(n)时间复杂度内从无序列表中找出第k小(或第k大)元素的算法。一个著名的线性时间选择算法是快速选择算法(QuickSelect),它是快速排序算法的一个变种。

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

// 交换两个元素的值

void swap(int *a, int *b) {

int temp = *a;

*a = *b;

*b = temp;

}

// 选择一个随机的基准值

int selectPivot(int *arr, int low, int high) {

int idx = low + rand() % (high - low);

swap(&arr[high], &arr[idx]);

return arr[high];

}

// 快速选择算法的分区函数

int partition(int *arr, int low, int high) {

int pivot = selectPivot(arr, low, high);

int i = low - 1;

for (int j = low; j < high; j++) {

if (arr[j] <= pivot) {

i++;

swap(&arr[i], &arr[j]);

}

}

swap(&arr[i + 1], &arr[high]);

return i + 1;

}

// 快速选择算法

int quickSelect(int *arr, int low, int high, int k) {

if (low == high)

return arr[low];

int pivotIndex = partition(arr, low, high);

if (k == pivotIndex) {

return arr[k];

} else if (k < pivotIndex) {

return quickSelect(arr, low, pivotIndex - 1, k);

} else {

return quickSelect(arr, pivotIndex + 1, high, k);

}

}

int main() {

int n, k, i;

scanf("%d", &n); // 读取数列长度

int arr[n];

scanf("%d", &arr[0]); // 读取第一个元素

for (i = 1; i < n; i++) {

scanf("%d", &arr[i]);

}

scanf("%d", &k); // 读取k值

// 计算第k小的元素的索引(从1开始)

int kthSmallest = quickSelect(arr, 0, n - 1, k - 1);

printf("The %dth smallest element is %d\n", k, kthSmallest);

return 0;

}

归并排序

#include<stdio.h>

//请在此处开始编写你的代码

#include<bits/stdc++.h>

using namespace std;

void Mergearray(int a[],int first,int mid,int last,int temp[]){

int i=first,j=mid+1;

int m=mid,n=last;

int k=0;

while(i<=m&&j<=n)

{

if(a[i]<a[j])

temp[k++]=a[i++];

else

temp[k++]=a[j++];

}

while(i<=m)

temp[k++]=a[i++];

while(j<=n)

temp[k++]=a[j++];

for(i=0;i<k;i++)

a[first+i]=temp[i];

}

void Mergesort(int a[],int first,int last,int temp[]) //将两个任意数组合并排序

{

if(first<last)

{

int mid=(first+last)/2;

Mergesort(a,first,mid,temp); //左边有序

Mergesort(a,mid+1,last,temp); //右边有序

Mergearray(a,first,mid,last,temp); //再将两个有序数组合并

}

}

bool MergeSort(int a[], int n)  

{  

int *p = new int[n];  //分配一个有n个int型元素的数组所占空间,并将该数组的第一个元素的地址赋给int *型指针p。

if (p == NULL)  

return false;  

Mergesort(a, 0, n - 1, p);  

delete[] p;  

return true;  

}

int main()

{

int a[1000];

int n;

printf("请输入数的个数:\n");

scanf("%d",&n);

printf("请输入要排序的数列:\n");

for(int i=0;i<n;i++)

scanf("%d",&a[i]);

MergeSort(a,n);

printf("排序结果为:");

for(int i=0;i<n;i++)

printf(" %d ",a[i]);

}

大整数乘法

背景:在科学计算中,无法计算非常大的整数,于是就有大整数乘法问题。(int存放4字节,float…已有的数据类型数据范围有限),硬件无法实现,只能靠软件(代码)实现了。

要求:求两个不超过200位的非负整数的积

#include<stdio.h>

#include<string.h>

#define N 100

int main()

{

int i, j, L[N];

char m[N], n[N];

scanf("%s %s", m, n);

int len1 = strlen(m);

int len2 = strlen(n);

memset(L, 0, sizeof(L));

for(i = 0; i < len1; i++)

for(j = 0; j < len2; j++)

L[i+j] += (m[len1 - i - 1] - '0') * (n[len2 - j - 1] - '0');

for(i = 0; i < len1 + len2; i++)

if(L[i] >= 10)

{

L[i+1] += L[i] / 10;

L[i] %= 10;

}

while(L[i] == 0)

i--;

while(i >= 0)

printf("%d", L[i--]);

return 0;

}

选k小数

给定一个长度为 n的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k个数。

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

// 随机选择枢纽元的索引

int randomPivot(int low, int high) {

return low + rand() % (high - low + 1);

}

// 交换两个元素的值

void swap(int *a, int *b) {

int temp = *a;

*a = *b;

*b = temp;

}

// 快速选择算法的分区函数

int partition(int arr[], int low, int high) {

int pivotIndex = randomPivot(low, high);

int pivotValue = arr[pivotIndex];

swap(&arr[pivotIndex], &arr[high]); // 将枢纽元放到数列的末尾

int i = low;

for (int j = low; j < high; j++) {

if (arr[j] < pivotValue) {

swap(&arr[i], &arr[j]);

i++;

}

}

swap(&arr[i], &arr[high]); // 将枢纽元放到正确的位置

return i;

}

// 快速选择算法

int quickSelect(int arr[], int low, int high, int k) {

if (low == high) {

return arr[low];

}

int pivotIndex = partition(arr, low, high);

if (k == pivotIndex) {

return arr[k];

} else if (k < pivotIndex) {

return quickSelect(arr, low, pivotIndex - 1, k);

} else {

return quickSelect(arr, pivotIndex + 1, high, k);

}

}

int main() {

int n, k, i;

scanf("%d %d", &n, &k); // 读取数列长度和k值

int arr[n];

for (i = 0; i < n; i++) {

scanf("%d", &arr[i]); // 读取数列

}

// 设置随机种子

srand((unsigned) time(NULL));

// 调用快速选择算法,查找第k小的数

int kthElement = quickSelect(arr, 0, n - 1, k - 1);

printf("%d\n", kthElement);

return 0;

}

查找一个整数数组中第二大数

实现一个函数,查找一个整数数组中第二大数

//请在此处开始编写你的代码

#include <stdio.h>

#include <limits.h>

int findSecondMax(int arr[], int n) {

int max = INT_MIN, secondMax = INT_MIN;

for (int i = 0; i < n; i++) {

if (arr[i] > max) {

// 更新第二大值,然后找到新的最大值

secondMax = max;

max = arr[i];

} else if (arr[i] > secondMax && arr[i] != max) {

// 更新第二大值

secondMax = arr[i];

}

}

return secondMax;

}

int main() {

int n, i;

scanf("%d", &n); // 读取数组长度

int arr[n];

for (i = 0; i < n; i++) {

scanf("%d", &arr[i]); // 读取数组元素

}

// 调用函数查找第二大的数

int secondMax = findSecondMax(arr, n);

printf("the second_max is: %d\n", secondMax);

return 0;

}

十个数选最小并返回位置

编程题

题目描述:

从键盘输入10个整数,找出其中的最小数及其位置

#include <stdio.h>

#include <math.h>

int min(int a[]) {

int x = a[0];

for (int i = 1; i < 10; i++) {

if (a[i] < x) {

x = a[i];

}

}

return x;

}

int main() {

int a[10];

for (int i = 0; i < 10; i++) {

scanf("%d", &a[i]);

}

int x = min(a);

for (int i = 0; i < 10; i++) {

if (a[i] == x) {

printf("最小数为:%d 位置为:%d", x, i);

}

}

return 0;

}

在二维有序矩阵中查找目标值的出现次数

给定一个 m x n 的二维有序矩阵,矩阵中可能包含重复元素,以及一个目标值 target,设计一个算法来计算矩阵中目标值的出现次数。矩阵具有以下特性:

每行的整数从左到右升序排列。

每列的整数从上到下升序排列。

#include <stdio.h>

#include <stdlib.h>

int searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {

int count = 0;

int row = 0;

int col = *matrixColSize - 1;

while (row < matrixSize && col >= 0) {

if (matrix[row][col] == target) {

count++;

col--;

}

else if (matrix[row][col] > target) {

col--;

}

else {

row++;

}

}

return count;

}

int main() {

int m, n;

printf("请输入矩阵的行数和列数:");

scanf("%d %d", &m, &n);

int** matrix = (int**)malloc(sizeof(int*) * m);

for (int i = 0; i < m; i++) {

matrix[i] = (int*)malloc(sizeof(int) * n);

}

printf("请输入有序矩阵的元素(按行输入):\n");

for (int i = 0; i < m; i++) {

for (int j = 0; j < n; j++) {

scanf("%d", &matrix[i][j]);

}

}

int target;

printf("请输入目标值:");

scanf("%d", &target);

int result = searchMatrix(matrix, m, &n, target);

printf("目标值 %d 出现的次数是:%d\n", target, result);

for (int i = 0; i < m; i++) {

free(matrix[i]);

}

free(matrix);

return 0;

}

在有序链表中的插入值

给定一个升序排列的有序链表和一个目标值,设计一个算法来找到目标值在有序链表中的插入位置,即将目标值插入到链表中后仍然保持有序。

#include <stdio.h>

#include <stdlib.h>

typedef struct ListNode {

int val;

struct ListNode* next;

} ListNode;

int searchInsert(ListNode* head, int target) {

int index = 0;

while (head != NULL && head->val < target) {

head = head->next;

index++;

}

return index;

}

ListNode* createNode(int val) {

ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));

if (newNode == NULL) {

printf("内存分配失败\n");

exit(1);

}

newNode->val = val;

newNode->next = NULL;

return newNode;

}

ListNode* createLinkedList() {

int n, val;

printf("请输入链表的长度:");

scanf("%d", &n);

ListNode* head = NULL;

ListNode* temp = NULL;

printf("请输入链表的元素(升序排列):");

for (int i = 0; i < n; i++) {

scanf("%d", &val);

ListNode* newNode = createNode(val);

if (head == NULL) {

head = newNode;

temp = head;

}

else {

temp->next = newNode;

temp = temp->next;

}

}

return head;

}

void freeLinkedList(ListNode* head) {

ListNode* temp;

while (head != NULL) {

temp = head;

head = head->next;

free(temp);

}

}

int main() {

ListNode* head = createLinkedList();

int target;

printf("请输入目标值:");

scanf("%d", &target);

int index = searchInsert(head, target);

printf("目标值 %d 的插入位置是:%d\n", target, index);

freeLinkedList(head);

return 0;

}

在有序链表中查找最接近目标值的节点值

给定一个升序排列的有序链表和一个目标值,设计一个算法来找到链表中最接近目标值的节点值。

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

typedef struct ListNode {

int val;

struct ListNode *next;

} ListNode;

// 创建新链表节点

ListNode *createNode(int data) {

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));

newNode->val = data;

newNode->next = NULL;

return newNode;

}

// 给定头节点,创建一个升序列表

ListNode *createSortedList(int *arr, int n) {

ListNode *head = NULL, *tail = NULL;

for (int i = 0; i < n; i++) {

tail = createNode(arr[i]);

if (!head) {

head = tail;

} else {

tail->next = head;

head = tail;

}

}

return head;

}

// 找到链表中最接近目标值的节点值

int findClosestValue(ListNode *head, int target) {

int closest = head->val;

ListNode *current = head;

while (current != NULL) {

if (abs(closest - target) > abs(current->val - target)) {

closest = current->val;

}

current = current->next;

}

return closest;

}

int main() {

int n, target, i;

scanf("%d", &n); // 读取链表的长度

int *arr = (int *)malloc(n * sizeof(int));

for (i = 0; i < n; i++) {

scanf("%d", &arr[i]); // 读取链表元素

}

scanf("%d", &target); // 读取目标值

// 创建升序列表

ListNode *head = createSortedList(arr, n);

// 找到最接近目标值的节点值

int closestValue = findClosestValue(head, target);

// 输出结果

printf("链表中最接近目标值 %d 的节点值是:%d\n", target, closestValue);

// 释放链表内存

while (head != NULL) {

ListNode *temp = head;

head = head->next;

free(temp);

}

free(arr);

return 0;

}

在有序链表中查找目标值的出现次数

给定一个升序排列的有序链表和一个目标值,设计一个算法来计算链表中目标值的出现次数。

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

typedef struct ListNode {

int val;

struct ListNode *next;

} ListNode;

// 创建新链表节点

ListNode *createNode(int data) {

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));

newNode->val = data;

newNode->next = NULL;

return newNode;

}

// 给定头节点,将数组元素插入到链表中

void insertToList(ListNode **head, int data) {

ListNode *newNode = createNode(data);

if (*head == NULL || (*head)->val >= data) {

newNode->next = *head;

*head = newNode;

} else {

ListNode *current = *head;

while (current->next != NULL && current->next->val < data) {

current = current->next;

}

newNode->next = current->next;

current->next = newNode;

}

}

// 计算链表中目标值的出现次数

int countOccurrences(ListNode *head, int target) {

int count = 0;

ListNode *current = head;

while (current != NULL) {

if (current->val == target) {

count++;

// 继续遍历直到数值改变,以便计算连续出现的次数

while (current->next != NULL && current->next->val == target) {

current = current->next;

count++;

}

}

current = current->next;

}

return count;

}

int main() {

int n, target, i;

scanf("%d", &n); // 读取链表的长度

ListNode *head = NULL;

for (i = 0; i < n; i++) {

int value;

scanf("%d", &value);

insertToList(&head, value);

}

scanf("%d", &target); // 读取目标值

// 计算目标值的出现次数

int count = countOccurrences(head, target);

// 输出结果

printf("目标值 %d 的出现次数是:%d\n", target, count);

// 释放链表内存

while (head != NULL) {

ListNode *temp = head;

head = head->next;

free(temp);

}

return 0;

}

在有序链表中查找目标值的最小索引

给定一个升序排列的有序链表和一个目标值,设计一个算法来查找链表中第一次出现目标值的位置。如果目标值存在于链表中,则返回第一次出现的位置索引(从0开始),否则返回-1。

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

typedef struct ListNode {

int val;

struct ListNode *next;

} ListNode;

// 创建新链表节点

ListNode *createNode(int data) {

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));

newNode->val = data;

newNode->next = NULL;

return newNode;

}

// 给定头节点,将数组元素插入到链表中

void insertToList(ListNode **head, int *arr, int index) {

ListNode *newNode = createNode(arr[index]);

if (*head == NULL || (*head)->val > newNode->val) {

newNode->next = *head;

*head = newNode;

} else {

ListNode *current = *head;

while (current->next != NULL && current->next->val < newNode->val) {

current = current->next;

}

newNode->next = current->next;

current->next = newNode;

}

}

// 查找链表中目标值的第一次出现位置

int findFirstOccurrence(ListNode *head, int target) {

int index = 0;

ListNode *current = head;

while (current != NULL) {

if (current->val == target) {

return index;

}

index++;

current = current->next;

}

return -1; // 如果没有找到目标值,则返回-1

}

int main() {

int n, target, i;

scanf("%d", &n); // 读取链表的长度

int *arr = (int *)malloc(n * sizeof(int));

for (i = 0; i < n; i++) {

scanf("%d", &arr[i]); // 读取链表元素

}

scanf("%d", &target); // 读取目标值

// 创建升序列表

ListNode *head = NULL;

for (i = 0; i < n; i++) {

insertToList(&head, arr, i);

}

// 查找目标值的第一次出现位置

int firstOccurrence = findFirstOccurrence(head, target);

// 输出结果

if (firstOccurrence != -1) {

printf("目标值 %d 的最小索引是:%d\n", target, firstOccurrence);

} else {

printf("目标值 %d 不存在于链表中\n", target);

}

// 释放链表和数组内存

while (head != NULL) {

ListNode *temp = head;

head = head->next;

free(temp);

}

free(arr);

return 0;

}

查找链表中的最大值

给定一个有序链表,设计一个算法来查找链表中的最大值。

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

typedef struct ListNode {

int val;

struct ListNode *next;

} ListNode;

// 创建新链表节点

ListNode *createNode(int data) {

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));

newNode->val = data;

newNode->next = NULL;

return newNode;

}

// 给定头节点,将数组元素插入到链表中

void insertToList(ListNode **head, int data) {

ListNode *newNode = createNode(data);

if (*head == NULL || (*head)->val < data) {

newNode->next = *head;

*head = newNode;

} else {

ListNode *current = *head;

while (current->next != NULL && current->next->val > data) {

current = current->next;

}

newNode->next = current->next;

current->next = newNode;

}

}

// 查找链表中的最大值

int findMaxValue(ListNode *head) {

ListNode *current = head;

int maxVal = current->val; // 假设第一个元素是最大值

while (current != NULL) {

if (current->val > maxVal) {

maxVal = current->val; // 找到更大的值,更新最大值

}

current = current->next;

}

return maxVal;

}

int main() {

int n, i;

scanf("%d", &n); // 读取链表的长度

ListNode *head = NULL;

for (i = 0; i < n; i++) {

int value;

scanf("%d", &value);

insertToList(&head, value);

}

// 查找最大值

int maxVal = findMaxValue(head);

// 输出结果

printf("链表中的最大值是:%d\n", maxVal);

// 释放链表内存

while (head != NULL) {

ListNode *temp = head;

head = head->next;

free(temp);

}

return 0;

}

查找链表中的目标值

给定一个有序链表,设计一个算法来查找链表中是否存在目标值 target。如果目标值存在,则返回目标值存在于链表中;否则,返回目标值不存在于链表中。

//请在此处开始编写你的代码

#include <stdio.h>

#include <stdlib.h>

typedef struct ListNode {

int val;

struct ListNode *next;

} ListNode;

// 创建新链表节点

ListNode *createNode(int data) {

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));

newNode->val = data;

newNode->next = NULL;

return newNode;

}

// 给定头节点,将数组元素插入到链表中

void insertToList(ListNode **head, int *arr, int index) {

if (*head == NULL) {

*head = createNode(arr[index]);

} else {

ListNode *current = *head;

while (current->next != NULL) {

current = current->next;

}

current->next = createNode(arr[index]);

}

}

// 查找链表中是否存在目标值

int existsTarget(ListNode *head, int target) {

ListNode *current = head;

while (current != NULL) {

if (current->val == target) {

return 1; // 目标值存在于链表中

}

current = current->next;

}

return 0; // 目标值不存在于链表中

}

int main() {

int n, target, i;

scanf("%d", &n); // 读取链表的长度

int *arr = (int *)malloc(n * sizeof(int));

for (i = 0; i < n; i++) {

scanf("%d", &arr[i]); // 读取链表元素

}

scanf("%d", &target); // 读取目标值

// 创建链表

ListNode *head = NULL;

for (i = 0; i < n; i++) {

insertToList(&head, arr, i);

}

// 查找目标值是否存在

int exists = existsTarget(head, target);

// 输出结果

if (exists) {

printf("目标值存在于链表中。\n");

} else {

printf("目标值不存在于链表中。\n");

}

// 释放链表内存

while (head != NULL) {

ListNode *temp = head;

head = head->next;

free(temp);

}

free(arr);

return 0;

}

寻找无序数组中的局部最小值

给定一个无序的整数数组 nums,设计一个算法来找到数组中的一个局部最小值。局部最小值定义为比其相邻元素小的元素。

//请在此处开始编写你的代码

#include <stdio.h>

// 函数用于找到数组中的局部最小值

int findLocalMin(int arr[], int n) {

for (int i = 1; i < n - 1; i++) {

if (arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {

return i; // 返回局部最小值的索引

}

}

return -1; // 如果没有找到局部最小值,则返回-1

}

int main() {

int n, i;

scanf("%d", &n); // 读取数组的长度

int arr[n];

for (i = 0; i < n; i++) {

scanf("%d", &arr[i]); // 读取数组元素

}

// 查找局部最小值的索引

int localMinIndex = findLocalMin(arr, n);

if (localMinIndex != -1) {

printf("数组中的局部最小值是:%d\n", arr[localMinIndex]);

} else {

printf("没有找到局部最小值。\n");

}

return 0;

}

寻找有序矩阵中的目标值

给定一个按行和列都按升序排列的 m x n 矩阵 matrix,以及一个目标值 target。如果目标值存在于矩阵中,则返回目标值存在于矩阵中;否则,返回目标值不存在于矩阵中。

#include<stdio.h>

#define ROWS 4

#define COLS 4

int searchMatrix(int matrix[ROWS][COLS],int target){

int row=0;

int col=COLS-1;

while(row<ROWS&&col>=0){

if(matrix[row][col]==target)

return 1;

else if(matrix[row][col]>target)

col--;

else

row++;

}

return 0;

}

int main(){

int matrix[ROWS][COLS];

int target;

printf("请输入%d x %d矩阵:\n",ROWS,COLS);

for(int i=0;i<ROWS;i++){

for(int j=0;j<COLS;j++){

scanf("%d",&matrix[i][j]);

}

}

printf("请输入目标值:\n");

scanf("%d",&target);

if(searchMatrix(matrix,target))

printf("目标值存在于矩阵中。\n");

else

printf("目标值不存在于矩阵中。\n");

return 0;

}

在旋转排序数组中查找最小值(减治)

整数数组

其中,整数数组表示旋转排序数组,假设数组中不存在重复元素,以空格分隔。

#include<stdio.h>

#include<stdlib.h>

int findMin(int arr[],int size){

if(size==1){

return arr[0];

}

int left=0,right=size-1;

while(left<right){

int mid=left+(right-left)/2;

if(arr[mid]>arr[right]){

left=mid+1;

}

else{

right=mid;

}

}

return arr[left];

}

int main(){

int size;

printf("请输入旋转排序数组的长度:\n");

scanf("%d",&size);

int*arr=(int*)malloc(size*sizeof(int));

if(arr==NULL){

printf("内存分配失败\n");

return 1;

}

printf("请输入旋转排序数组的元素:\n");

for(int i=0;i<size;i++){

scanf("%d",&arr[i]);

}

int min=findMin(arr,size);

printf("旋转排序数组中的最小值为:%d\n",min);

free(arr);

return 0;

}

        

         

        

            

        

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值