【问题】

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. [转]通过AngularJS directive对bootstrap日期控件的的简单包装

    本文转自:http://www.cnblogs.com/Benoly/p/4109460.html 最近项目上了AngularJS,而原来使用的日期控件的使用方式也需要改变,于是开始了倒腾,看了官方的 ...

  2. 深度优先搜索 codevs 1064 虫食算

    codevs 1064 虫食算 2004年NOIP全国联赛提高组  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 所 ...

  3. UVA 103 Stacking Boxes --LIS

    实际上是一个扩展维度的矩形嵌套问题. 一个物体能嵌入另一个物体中,当且仅当这个物体的所有维度的长度都小于另外一个(本题是小于等于),又因为可以旋转等变换,所以干脆将每个箱子的边从小到大排序,以便于判断 ...

  4. UESTC 1080 空心矩阵

    这题理解题意最重要,千万不要理解错.题意是取矩阵的左上角,所以能切掉的都要切掉,是能形成三角形的形成三角形,不能的尽量割掉最大.代码借鉴了一位大牛的,如下: #include<iostream& ...

  5. C# Process执行bat

    Process类 System.Diagnostics 命名空间提供类,使您能够与系统进程.事件日志和性能计数器进行交互. Process类提供对本地和远程进程的访问并使您能够启动和停止本地系统进程. ...

  6. IO流的练习3 —— 复制多级文件夹下的指定文件并改名

    需求:复制指定目录下的指定文件,并修改后缀名. 指定的文件是:.java文件. 指定的后缀名是:.jad 数据源所在文件夹:C:\Users\Administrator\Desktop\记录 目的地所 ...

  7. Android自定义进度条颜色

    这个没法了只能看源码了,还好下载了源码, sources\base\core\res\res\ 下应有尽有,修改进度条颜色只能找progress ,因为是改变样式,首先找styles.xml ? 1 ...

  8. S2--《深入.NET平台和C#编程》

    第一章    深入.NET框架 1.1  Microsoft  .NET框架概述 .NET框架的优势 * 提供了一个面向对象的编程环境,完全支持面向对象编程,.NET 框架提高了软件的可复用性,可扩展 ...

  9. POJ 2406 Power Strings

    F - Power Strings Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u S ...

  10. 09Spring_AOP介绍和java本身的动态代理以及cglib代理

    Aspect Oriented Programming 面向切面编程 1. 业界 AOP 实际上 OOP (面向对象编程 ) 延伸 ----  OOP编程语言. AOP设计思想,下面给出一张AOP的设 ...