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树,找到它的最大深度.最大深度是从根节点到 ...
随机推荐
- 边工作边刷题:70天一遍leetcode: day 84-2
要点:这题是combination的应用,从左向右想比从右向左容易. 因为有结果从小到大的要求,暗示用combintion而不是permutation 其实就是从小到大验证因子,每个因子和其对称因子立 ...
- 线性代数与MATLAB2
已知矩阵 求它们的特征值和特征向量,并绘制特征向量图,分析其几何意义 运行Meigvector.m A1=[-1 3;2 5]; A2=[1 -2;-1 5]; A3=[1 2;2 4]; A4=[2 ...
- VS 扩展推荐
Visual Studio 工欲善其事,必先利器.本着这样的观念,对于经常使用的工具,我喜欢去研究研究,帮助我提高效率. Visual Studio Microsoft Visual Studio(简 ...
- [3D跑酷] UI事件处理系统
在我们的Unity游戏项目中,GUI的表现采用NGUI.记录一下我们的处理方式: 需要解决的问题 1.需要处理大量按钮的点击事件 2.需要处理界面跳转事件 3.需要处理界面元素更新事件 解决方案 GU ...
- R之字符串连接函数paste
函数paste的一般使用格式为: paste(..., sep = " ", collapse = NULL) 其中...表示一个或多个R可以被转化为字符型的对象:参数sep表示分 ...
- PHP版本VC6和VC9、Non Thread Safe和Thread Safe的区别
链接:http://www.cnblogs.com/neve/articles/1863853.html 想更新个PHP的版本,PHP的windows版本已经分离出来了,见http://windows ...
- android intent隐式调用之一个应用程序启动另一个应用程序
理解Intent的关键之一是理解清楚Intent的两种基本用法:一种是显式的Intent,即在构造Intent对象时就指定接收者,这种方式与普通的函数调用类似:另一种是隐式的Intent,即Inten ...
- High Performance Animations
http://www.html5rocks.com/zh/tutorials/speed/high-performance-animations/
- webpack+react+redux+es6
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- ThinkPHP 3.2.3 ----- 验证码
显示验证码 首先在Home/Controller下创建一个公共控制器PublicController 1 <?php 2 namespace Home\Controller; 3 4 use T ...