C/C++语言算法题——替换
【问题】
Description
给定一个有限长度的非负整数序列。一次操作是指从第一个元素开始,依次把数列中的每个数替换为它右边比它小的数的个数。对该数列不断进行这个操作。总有一个时刻该数列将不再发生改变(即此时每个数都恰好等于它右边比它小的数的个数)。例如给定数列:
5, 44, 19, 6, 49, 1, 27, 19, 50, 20
连续进行五次操作后,依次得到新数列如下:
1, 6, 2, 1, 4, 0, 2, 0, 1, 0
3, 8, 5, 3, 5, 0, 3, 0, 1, 0
4, 8, 6, 4, 5, 0, 3, 0, 1, 0
5, 8, 7, 5, 5, 0, 3, 0, 1, 0
5, 8, 7, 5, 5, 0, 3, 0, 1, 0
其中,第四次操作后,数列不再发生改变。
对给定数列,循环执行上述操作,直到其不再改变为止,输出最后得到的数列。
Input
第1行:一个整数T(1≤T≤10)为问题数。
对于每组测试数据:
第1行是一个正整数:数列长度N ( 2 < N≤30 );
第2行有N个正整数:分别为该数列第1至第N个元素的值a1,a2,…,aN( a1,a2,…, aN均为1 - 1000的数),每两个整数之间用一个空格分开。
Output
对于每个问题,输出一行问题的编号(0开始编号,格式:case #0: 等)。
然后在一行中依次输出最后数列的所有元素,每两个元素之间用一个空格分开,最后一个元素后面没有空格。
Sample Input
3
10
5 44 19 6 49 1 27 19 50 20
10
3 2 7 10 9 8 8 5 1 5
10
12 12 19 19 7 10 9 6 18 9
Sample Output
case #0:
5 8 7 5 5 0 3 0 1 0
case #1:
9 2 3 6 5 3 3 2 0 0
case #2:
6 6 6 6 3 4 3 0 1 0
【解题报告】
算法本身很容易实现,但是问题是我不清楚应当如何判断算法何时结束,也就是如何判断“两次变换所得到的新数组相等”。如果有更好的算法请不吝赐教。
#include <iostream>
using namespace std;
#define TRUE 1
#define FALSE 0 int isSame(const int*, const int*, const int);
void setArray(int*, int);
void outputArray(const int*, const int);
void process(int*, int);
int* clone(const int*, int); int main()
{
int T;
cin>>T;
for(int c = ; c < T; c++)
{
int N;
cin>>N;
int* arr = new int[N];
setArray(arr,N);
for(;;) /* 这里我实在想不出该如何简便地判断参加变换的数组是否发生变化,因此 */
{ /* 只能通过备份前一次变换的结果和当次运算结果作比较 */
int* temp = clone(arr,N);
process(arr,N); /* 虽然能够AC,但是这肯定不是最优的算法 */
if(isSame(arr,temp,N)) /* 因此如有更好的,时间复杂度更低的算法还望不吝赐教奥 */
{
delete[] temp;
break;
}
}
cout<<"case #"<<c<<":"<<endl;
outputArray(arr,N);
delete[] arr;
}
return ;
} /** 判断两个同等长度的数组是否相等
@param arr1 数组1
@param arr2 数组2
@param N 数组1和2的长度
@returns 相等返回1,否则返回0
*/
int isSame(const int* arr1, const int* arr2, const int N)
{
for(int i = ; i < N; i++)
{
if(arr1[i] != arr2[i])
return FALSE;
}
return TRUE;
} /**
通过标准输入设置数组的各元素
@param arr 待填充的数组
@param n 数组长度
*/
void setArray(int* arr, int n)
{
int t;
for(int i = ; i < n; i++)
{
cin>>t;
arr[i] = t;
}
} /**
输出数组
@param arr 要输出的数组
@param N 数组长度
*/
void outputArray(const int* arr, const int N)
{
for(int i = ; i < N; i++)
{
cout<<arr[i];
if(i != N-) cout<<' ';
else cout<<'\n';
}
} /**
处理算法
循环处理每一个元素,将其修改为它后面比它小的元素的个数
@param arr 要处理的数组
@param N 数组长度
*/
void process(int* arr, int N)
{
for(int i = ; i < N; i++)
{
int count = ;
for(int j = i+; j < N; j++)
{
if(arr[j] < arr[i])
count++;
}
arr[i] = count;
}
} /**
克隆数组,将一个数组克隆为另一个数组,
使得两个数组中的各元素相同,但他们的首指针不同。
@param arr 待克隆的源数组
@param N 数组长度
@returns 克隆出的新数组
*/
int* clone(const int* arr, int N)
{
int* temp = new int[N];
for(int i = ; i < N; i++)
{
temp[i] = arr[i];
}
return temp;
}解题代码
解题代码
【优化】
根据hoodlum1980的建议。将process函数改为
bool process(int* arr, int N)
{
bool changed = false;
for(int i = ; i < N; i++)
{
int count = ;
for(int j = i+; j < N; j++)
{
if(arr[j] < arr[i])
count++;
}
if(arr[i] != count)
{
arr[i] = count;
changed = true;
}
}
return changed;
}
主函数相应部分改为
while(process(arr,N));
出处:http://acm.cs.ecnu.edu.cn/problem.php?problemid=2993
C/C++语言算法题——替换的更多相关文章
- 《剑指Offer》算法题——替换空格
题目:请实现一个函数,将一个字符串中的空格替换成“ % 20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are % 20Happy. class Solution ...
- 面试经典算法题集锦——《剑指 offer》小结
从今年 3 月份开始准备找实习,到现在校招结束,申请的工作均为机器学习/数据挖掘算法相关职位,也拿到了几个 sp offer.经历这半年的洗礼,自己的综合能力和素质都得到了一个质的提升. 实话说对于未 ...
- LeetCode算法题-Flood Fill(Java实现)
这是悦乐书的第306次更新,第325篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第173题(顺位题号是733).图像由二维整数数组表示,每个整数表示图像的像素值(从0到 ...
- LeetCode算法题-Baseball Game(Java实现)
这是悦乐书的第288次更新,第305篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第156题(顺位题号是682).你现在是棒球比赛点记录器.给定一个字符串列表,每个字符串 ...
- LeetCode算法题-Maximum Product of Three Numbers(Java实现)
这是悦乐书的第275次更新,第291篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第143题(顺位题号是628).给定一个整数数组,从其中找出三个数,使得乘积最大.例如: ...
- LeetCode算法题-Distribute Candies(Java实现)
这是悦乐书的第266次更新,第279篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第133题(顺位题号是575).给定具有偶数长度的整数数组,其中该数组中的不同数字表示不 ...
- LeetCode算法题-Reshape the Matrix(Java实现)
这是悦乐书的第264次更新,第277篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第131题(顺位题号是566).在MATLAB中,有一个非常有用的函数叫做'reshap ...
- LeetCode算法题-Array Partition I(Java实现)
这是悦乐书的第262次更新,第275篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第129题(顺位题号是561).给定一个2n个整数的数组,你的任务是将这些整数分组为n对 ...
- LeetCode算法题-Maximum Depth of N-ary Tree(Java实现)
这是悦乐书的第261次更新,第274篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第128题(顺位题号是559).给定n-ary树,找到它的最大深度.最大深度是从根节点到 ...
随机推荐
- 【MVC 4】5.SportsSore —— 一个真实的应用程序
作者:[美]Adam Freeman 来源:<精通ASP.NET MVC 4> 前面建立的都是简单的MVC程序,现在到了吧所有事情综合在一起,以建立一个简单但真实的电子商务应用 ...
- 深度优先搜索 codevs 1065 01字符串
codevs 1065 01字符串 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 输出仅有0和1组成的长度为n的字符串,并且 ...
- 怎样绘制ZBrush中的纹理
利用ZBrush的内置插件“投影大师”和“Polypainting”纹理贴图能够快速实现纹理的绘制.本文将对这两种方法的应用流程做一个介绍. 查看跟多内容请直接前往:http://www.zbrush ...
- AC日记——codevs 1086 栈 (卡特兰数)
题目描述 Description 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). ...
- Flex xml编辑器(老外写的)
github上的一个项目老外写的xml编辑器,灵活利用了Tree的labelFunction实现节点运行时展现.开源地址是 https://github.com/softinsure/XML-Edit ...
- java 20 -3 递归之删除特定目录下的特定文件
/* 需求:删除H:\demo目录下的带内容的文件 分析: A:封装该目录 B:获取该目录下所有的文件或文件夹的File数组 C:遍历该File数组,获取每一个File对象 D:判断所遍历的FIle对 ...
- java 8-7 接口
1. 接口的特点: A:接口用关键字interface表示 interface 接口名 {} B:类实现接口用implements表示 class 类名 implements 接口名 {} C:接口不 ...
- Springmvc返回JSON乱码问号
@RequestMapping(value="/book/getBook.do", produces = "text/html;charset=UTF-8") ...
- UIVisualEffectView为视图添加特殊效果
在iOS 8后,苹果开放了不少创建特效的接口,其中就包括创建毛玻璃(blur)的接口. 通常要想创建一个特殊效果(如blur效果),可以创建一个UIVisualEffectView视图对象,这个对象提 ...
- C# Winform关于控件TabControl闪烁的问题
自己重写了一个Form,然后再该form上放一个TabControl鼠标移上去会闪烁,经过网上查找解决方案,最后总算是解决了....下面附上代码: 重写一个TabControl代码如下: using ...