【问题】

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++语言算法题——替换的更多相关文章

  1. 《剑指Offer》算法题——替换空格

    题目:请实现一个函数,将一个字符串中的空格替换成“ % 20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are % 20Happy. class Solution ...

  2. 面试经典算法题集锦——《剑指 offer》小结

    从今年 3 月份开始准备找实习,到现在校招结束,申请的工作均为机器学习/数据挖掘算法相关职位,也拿到了几个 sp offer.经历这半年的洗礼,自己的综合能力和素质都得到了一个质的提升. 实话说对于未 ...

  3. LeetCode算法题-Flood Fill(Java实现)

    这是悦乐书的第306次更新,第325篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第173题(顺位题号是733).图像由二维整数数组表示,每个整数表示图像的像素值(从0到 ...

  4. LeetCode算法题-Baseball Game(Java实现)

    这是悦乐书的第288次更新,第305篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第156题(顺位题号是682).你现在是棒球比赛点记录器.给定一个字符串列表,每个字符串 ...

  5. LeetCode算法题-Maximum Product of Three Numbers(Java实现)

    这是悦乐书的第275次更新,第291篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第143题(顺位题号是628).给定一个整数数组,从其中找出三个数,使得乘积最大.例如: ...

  6. LeetCode算法题-Distribute Candies(Java实现)

    这是悦乐书的第266次更新,第279篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第133题(顺位题号是575).给定具有偶数长度的整数数组,其中该数组中的不同数字表示不 ...

  7. LeetCode算法题-Reshape the Matrix(Java实现)

    这是悦乐书的第264次更新,第277篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第131题(顺位题号是566).在MATLAB中,有一个非常有用的函数叫做'reshap ...

  8. LeetCode算法题-Array Partition I(Java实现)

    这是悦乐书的第262次更新,第275篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第129题(顺位题号是561).给定一个2n个整数的数组,你的任务是将这些整数分组为n对 ...

  9. LeetCode算法题-Maximum Depth of N-ary Tree(Java实现)

    这是悦乐书的第261次更新,第274篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第128题(顺位题号是559).给定n-ary树,找到它的最大深度.最大深度是从根节点到 ...

随机推荐

  1. noip2008普及组4题题解-rLq

    (啊啊啊终于补到了今天的作业了) 本题地址:http://www.luogu.org/problem/show?pid=1058 题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣 ...

  2. 关于CSS中的字体尺寸设置 em rem等

    常用单位 在CSS中可以用很多不同的方式来设定字体的尺寸.一般来说,这些单位被分成两大类:绝对单位(absolute)和相对单位(relative). 绝对单位在大多数情况下是相对于某些实际量度而言的 ...

  3. 2014 Super Training #4 E Paint the Grid Reloaded --联通块缩点+BFS

    原题: ZOJ 3781 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 题意: 给一个n*m的X,O构成的格子,对 ...

  4. UVA 11235 Frequent Values ---RMQ

    大白书上的例题,具体讲解见大白书,最好用用一个Log数组直接求k,这样就是纯O(1)了 #include <iostream> #include <cstdio> #inclu ...

  5. Unity 2D Touch Movement

    Demo试玩(Kongregate既然也有广告时间了 --!)http://www.kongregate.com/games/zhaoqingqing/2d-touch-movement 操作步骤 1 ...

  6. TestLink学习六:TestLink1.9.13工作使用小结

    Testlink是一款强大的用例追踪和管理工具.测试管理注重的实际上就是一个流程. 1.默认当测试用例同名时,就会有提示.(以前版本需要修改配置) 2.测试用例序号:(缺点) 1)删除一个测试用例之后 ...

  7. phpmyadmin后台拿shell方法总结

    方法一: CREATE TABLE `mysql`.`xiaoma` (`xiaoma1` TEXT NOT NULL ); INSERT INTO `mysql`.`xiaoma` (`xiaoma ...

  8. (转载)java多态(2)-------Java转型(向上或向下转型)

    5.13.1 向上转型 我们在现实中常常这样说:这个人会唱歌.在这里,我们并不关心这个人是黑人还是白人,是成人还是小孩,也就是说我们更倾向于使用抽象概念“人”.再例如,麻雀是鸟类的一种(鸟类的子类), ...

  9. ng-bind的使用

    由于JS是单线程的,当HTML页面执行alert的时候,会中断下面代码的运行,所以为了良好的用户体验,当需要在页面使用{{name}}的时候,通常不这样直接输出,而是用ng-bind绑定model数据 ...

  10. immutability-javascript

    https://www.sitepoint.com/immutability-javascript/