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树,找到它的最大深度.最大深度是从根节点到 ...
随机推荐
- CANopen DS301协议中文翻译V03版
V0.1版PDF格式供下载参考,只是全面框架翻译,会有大量错误和不确定的地方,希望读者积极参与校对,提供修改意见,完善译文.下载 V0.2版校对提前完成,下载地址 V0.3版使用GitBook编辑(h ...
- python3使用套接字遇到TypeError: 'str' does not support the buffer interface如何解决
这是我查看的博客 http://blog.csdn.net/chuanchuan608/article/details/17915959 直接引用里面的关键语句: When you use clien ...
- Bellman-Ford算法判负环
算法思想:如果没有负权回路,dis数组应该会在n-1次松弛之后结束. 算法复杂度:O(n*m).比Dijkstra算法复杂度要高. 代码: bool Bellman_Ford(int s) { int ...
- FZU1894 志愿者选拔 --单调队列
做法:维护一个单调递减序列,只需输出序列中的第一个元素即可. 对于命令我们可以进行不同的处理: 如果是Q命令,则判断当前队列中是否仍有元素,如果没有则输出-1,如果有则直接输出队首. 如果是G命令,则 ...
- C++基础笔记(四)C++内存管理
析构函数 * 析构函数在对象所占用内存释放时调用,通常用来释放相关的资源 * 析构函数就是一个特殊的类成员函数,它是构造函数相反 构造函数:对象在分配内存之后,立即调用 析构函数:对象在内存被释放之前 ...
- java14-4 Pattern和Matcher类的使用
获取功能 Pattern和Matcher类的使用 模式和匹配器的基本使用顺序 import java.util.regex.Matcher; import java.util.regex.Pat ...
- Android 手势识别类 ( 三 ) GestureDetector 源码浅析
前言:上 篇介绍了提供手势绘制的视图平台GestureOverlayView,但是在视图平台上绘制出的手势,是需要存储以及在必要的利用时加载取出手势.所 以,用户绘制出的一个完整的手势是需要一定的代码 ...
- sqlzoo.net刷题4
SELECT name, continent FROM world a WHERE population > ( FROM world b WHERE a.continent = b.conti ...
- 12个JavaScript技巧
转自:http://web.jobbole.com/86146/ 在这篇文章中将给大家分享12个有关于JavaScript的小技巧.这些小技巧可能在你的实际工作中或许能帮助你解决一些问题. 使用!!操 ...
- 理解SQL Server中的权限体系(上)----主体
原文:http://www.cnblogs.com/CareySon/archive/2012/04/10/mssql-security-principal.html 简介 权限两个字,一个权力,一个 ...