算法题(编程)

目录

1. 鸡兔同笼问题

2. 猴子吃桃问题

3. 代码填空

4. 折半查找‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

5. 插入排序‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

6. 图着色问题‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

7. 使用分治法进行归并排序

8. 使用减治法进行堆排序

9. 程序改错(被注释掉的程序语句有错误)‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫


1. 鸡兔同笼问题

类型:约束条件比经典鸡兔同笼问题宽松,无头的个数约束,直接模拟法。‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬


描述

【问题】笼子里有若干只鸡和兔子,鸡有两只脚、兔子有四只脚,没有例外情况。已知笼子里脚的个数,问笼子里至多有多少只动物?至少有多少只动物?‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

【想法】对于同样数目的动物,鸡脚的总数肯定比兔子脚的总数要少,因此在计算笼子里至多有多少只动物时,应该把脚都算作鸡脚,在计算笼子里至少有多少只动物时,应该尽可能把脚都算作兔子脚。‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输入

脚的个数(大于0的整数)‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输出

至多有多少只动物,至少有多少只动物,其中兔子多少只。(输出中标点符号为中文,无需加换行符)‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

示例

(点击编辑器左上角{;}按钮编辑代码框)‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输入
-111
输出
不合常理

输入
333
输出
不合常理

输入
6
输出
至多有3只动物,至少有2只动物,其中1只是兔子。
#include <iostream>
using namespace std;
int main()
{
    int feets, maxNum, minNum,rabbits;
    cin>>feets;//把其余代码写在下面:
    if(feets <= 0 || feets % 2 != 0) {
    	cout << "不合常理";
	}else{
		maxNum = feets / 2;
		minNum = feets / 4;   
   cout << "至多有"<<maxNum<<"只动物,至少有"<<minNum<<"只动物,其中兔子"<<minNum<<"只。";
    	}
	return 0;
}

2. 猴子吃桃问题

类型:递推法之逆推‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

描述

一只猴子摘了很多桃子,每天吃现有桃子的一半多一个,到第n天时只有一个桃子,问原有桃子多少个?

输入

一个非负整数。‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输出

一个非负整数。不加换行符。‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

示例

(点击编辑器左上角{;}按钮编辑代码框)‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输入
5

输出
46
#include <iostream>
using namespace std;
int MonkeyPeach(int n)
{
    int i, num = 1;
    for(i=n-1;i>=1;i--)
        num=(num+1)*2
    return num;
}
int main()
{   int n;
    cin>>n;
    cout << MonkeyPeach(n);
    return 0;
}

3. 代码填空

描述

给定一个包含正整数的 m×n 网格,(为降低难度m=5,n=3,存储在数组dist[5][3]中。)每次只能向下或者向右移动一步,定义路径长度是路径上经过的整数之和。请找出一条从左上角(位置为(0,0))到位置(k,l)的路径,使得路径长度最大。(注意,是求最长路径!!!)‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输入

空格分隔的两个非负整数,表示目的方格的行标k和列标l。例如 4 2‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输出

从左上角(位置(0,0))到位置(k,l)的最长路径的长度。例如396

#include <iostream>
using namespace std;
int main()
{
    int m=5,n=3;
    int a[5][3]={ 8,75,92, 6,65,71, 5,63,7, 5,87,90, 76,7,8 };
    int dist[m][n], path[m][n], i, j,k,l;
    cin>>k>>l;
    dist[0][0] = a[0][0];
    path[0][0] = 0;
    for (j = 1; j <m ; j++)                     //填写第0行
    {
        dist[0][j] = dist[0][j-1] + a[0][j];
        path[0][j] = 1;
    }
    for (i = 1; i <n; i++)                     //填写第0列
    {
        dist[i][0] = dist[i-1][0] + a[i][0];
        path[i][0] = 0;
    }
    for (i = 1; i < m; i++)                                //填写每一行
        for (j = 1; j <n; j++)
            if (dist[i-1][j] > dist[i][j-1])
            {
                ##### dist[i][j] = dist[i-1][j] + a[i][j];
                path[i][j] = 0;
            }
            else
            {
                #####  dist[i][j] = dist[i][j-1] + a[i][j];
                path[i][j] = 1;
            }
    cout<<dist[k][l];//返回最优值
    return 0;
}

4. 折半查找‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬


描述

使用减治法进行折半查找

#include 
using namespace std;

int BinSearch(int r[ ], int n, int k);

int main( )
{
int i, index, n = 9, k, r[n] = {2, 3, 5, 6, 8, 10, 15, 18, 20};
for (i = 0; i < n; i++)
cout< cout< cout<<"请输入待查值:";
cin>>k;
index = BinSearch(r, n, k);
if (index == 0) cout<<"查找失败"< else cout<<"查找成功,序号是:"< return 0;
}

int BinSearch(int r[ ], int n, int k) 
{
int mid, low = 0, high = n - 1; 
while (low <= high) //当查找区间存在
{ 
mid = (low + high) / 2; 
if (k < r[mid]) ### high = mid - 1;
else if (k > r[mid]) ### low = mid + 1; 
else return mid + 1; //查找成功,返回元素序号
}
return 0; //查找失败,返回0
}

5. 插入排序‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬


描述

使用减治法进行插入排序

#include 
using namespace std;

void InsertSort(int r[ ], int n);

int main( )
{
int i, n = 10, r[n] = {0, 3, 18, 5, 8, 6, 10, 2, 15, 20};
for (i = 1; i < n; i++)
cout< cout< InsertSort(r, n);
for (i = 1; i < n; i++)
cout< cout< return 0;
}

void InsertSort(int r[ ], int n)
{ 
int i, j;
for (i = 2; i <= n; i++) //从第2个记录开始执行插入操作
{ 
######  r[0] = r[i]; //暂存待插记录,设置哨兵
for (j = i - 1; r[0] < r[j]; j--) //寻找插入位置
#####  r[j+1] = r[j]; //记录后移
r[j+1] = r[0]; 
}
}

6. 图着色问题‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬


描述

使用贪心法解决图着色问题

#include 
using namespace std;

int ColorGraph(int arc[100][100] , int n, int color[ ]);

int main( )
{
int arc[100][100] = {{0,1,0,0,0},{1,0,1,1,0},{0,1,0,0,1},{0,1,0,0,1},{0,0,1,1,0}};
int i, n = 5, color[n];
cout<<"需要颜色数为:"< cout<<"着色情况为:"; 
for (i = 0; i < n; i++)
cout< cout< return 0;
}



int ColorGraph(int arc[100][100] , int n, int color[ ])
{
int i, j, k = 0, flag = 1; 
while (flag == 1)
{
k++; flag = 0; //取下一种颜色
for (i = 0; i < n; i++)
{
if (color[i] != 0) continue; //顶点i已着色
##### color[i] = k; //顶点i着颜色k
for (j = 0; j < n; j++) 
if (arc[i][j] == 1 && color[i] == color[j]) break;
if (j < n) //发生冲突,取消涂色
{
##### color[i] = 0; 
flag = 1;
}
}
}
return k;
}

7. 使用分治法进行归并排序

#include 
using namespace std;

void Merge(int r[ ], int s, int m, int t);
void MergeSort(int r[ ], int s, int t);

int main( )
{
int i, n = 8, r[8] = {8,3,2,6,7,1,5,4};
MergeSort(r, 0, n-1);
for (i = 0; i < n; i++)
cout< return 0;
}

void Merge(int r[ ], int s, int m, int t) 
{
int r1[t];
int i = s, j = m + 1, k = s;
while (i <= m && j <= t)
{ 
if (r[i] <= r[j]) r1[k++] = r[i++]; //较小者放入r1[k]
else r1[k++] = r[j++]; 
}
while (i <= m) //处理第一个子序列剩余记录
#####  r1[k++] = r[i++]; 
while (j <= t) //处理第二个子序列剩余记录
#####  r1[k++] = r[j++]; 
for (i = s; i <= t; i++) //将合并结果传回数组r
r[i] = r1[i];
}

void MergeSort(int r[ ], int s, int t) //对序列r[s]~r[t]进行归并排序
{ 
if (s == t) return; //只有一个记录,已经有序
else 
{ 
int m = (s + t)/2; //划分
MergeSort(r, s, m); //归并排序前半个子序列
MergeSort(r, m+1, t); //归并排序后半个子序列
Merge(r, s, m, t); //合并两个有序子序列
}
}

8. 使用减治法进行堆排序

#include 
using namespace std;

void SiftHeap(int r[ ], int k, int n);
void HeapSort(int r[ ], int n);

int main( )
{
int i, n = 9, r[n] = {3, 18, 5, 8, 6, 10, 2, 15, 20};
for (i = 0; i < n; i++)
cout< cout< HeapSort(r, n);
for (i = 0; i < n; i++)
cout< cout< return 0;
}

void SiftHeap(int r[ ], int k, int n)
{
int i, j, temp;
i = k; j = 2 * i + 1; 
while (j < n) //筛选还没有进行到叶子
{
if (j < n-1 && r[j] < r[j+1]) j++; //比较i的左右孩子,j为较大者
if (r[i] > r[j]) //根结点已经大于左右孩子中的较大者
break; 
else 
{
temp = r[i]; #####  r[i] = r[j]; #####   r[j] = temp; //将被筛结点与结点j交换
i = j; j = 2 * i + 1; //被筛结点位于原来结点j的位置
}
}
}

void HeapSort(int r[ ], int n) 
{
int i, temp;
for (i = (n-1)/2; i >= 0; i--) //初始建堆,最后一个分支的下标是(n-1)/2
SiftHeap(r, i, n) ; 
for (i = 1; i <= n-1; i++) //重复执行移走堆顶及重建堆的操作
{
temp = r[0]; r[0] = r[n-i]; r[n-i] = temp;
SiftHeap(r, 0, n-i); //只需调整根结点
}
}

9. 程序改错(被注释掉的程序语句有错误)‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬


描述

假设有面值为5元、2元、1元、5角、2角、1角的货币,需要找给顾客n角现金,付款问题要求找到一个付款方案,本题要求:贪心法求启发解,付出的货币张数为多少?‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输入

一个非负整数,应找金额,单位为角。例如:100‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

输出

一个非负整数(货币张数)。例如:2

#include <iostream>
using namespace std;
int main()
{
    int money[6] = {50, 20, 10, 5, 2, 1}, i, cnt = 0, n;
    cin>>n;
    for (i = 0; i < 6; i++) /*选取面值依次试探*/
    {
        //if (n <= money[i])     #### if (n >= money[i])
        {
          //  cnt+=n%money[i];   #### cnt+=n/money[i];
           // n = n/money[i];    #### n = n % money[i];
           // if(n)break;        #### if(!n)break;
        }
    }
    //cout >> cnt;               #### cout << cnt;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值