度度熊有一个N个数的数组,他想将数组从小到大
排好序,但是萌萌的度度熊只会下面这个操作:
任取数组中的一个数然后将它放置在数组的最后一个位置。
问最少操作多少次可以使得数组从小到大有序?
首先输入一个正整数N,接下来的一行输入N个整数。(N <= 50, 每个数的绝对值小于等于1000)
输出一个整数表示最少的操作次数。
4 19 7 8 25
2
importjava.util.Scanner;publicclassMain {// 思路是这样的,这串数字可以分为两类:一类是不动数另一类是动数。动数的个数就是算法要移动的次数。// 不动数满足两个条件:1.后面的数都大于该数。并且,2.前面最小动数大于该数。// 动数和不动数刚好相反:1.后面的数至少有一个数大于该数。或者2.前面最小动数小于该数。// 不是不动数的数就是动数。只需要找到所有动数个数,就能得到算法移动次数。publicstaticvoidmain(String args[]){Scanner sc = newScanner(System.in);intpoint_num = sc.nextInt();int[] list = newint[point_num];for(inti = 0; i < list.length; i++){list[i] = sc.nextInt();}intmove_count = 0; // 记录动数的个数。intmin_move_value = 1001; // 初始化最小动数的值。for(inti = 0; i < list.length; i++){if(min_move_value < list[i]){move_count++; // 满足动数条件2continue;}for(intj = i+1; j < list.length; j++){if(list[i]>list[j]){move_count++; // 满足动数条件1min_move_value = list[i]; // 该动数与最小动数值比较break;}}}System.out.println(move_count);}}
//大概的想法就是,首先怎样移操作最少:首先找到数组里面最小的一个,显然这个数是不需要移动的。 // 同时第二小,并且在第一小后面也不需要移动,以此类推,直到出现了一个第k小并且它在第k-1小前面 // 显然这个时候需要移动了,一旦这个数移动了,后面所有的第k+1到n小的数都需要移动,因此总的移动次数为n-k。 import java.util.Scanner; import java.util.Arrays; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int n = sc.nextInt(); int[] num = new int[n]; int[] sorted = new int[n]; int min_op = 0; for(int i=0;i<n;i++){ num[i] = sc.nextInt(); sorted[i] = num[i]; } Arrays.sort(sorted); for(int i=1;i<n;i++){ int forward = 0; int backward = 0; for(int j=0;j<n;j++){ if(num[j]==sorted[i-1])forward=j; if(num[j]==sorted[i])backward=j; } if(backward<forward){ min_op = n-i; break; } } System.out.println(min_op); } } }
#include <vector> #include <algorithm> using namespace std; int main() { int n; cin>>n; vector<int> vec(n); for(int i=0;i<n;i++) { cin>>vec[i]; } vector<int> vec2(vec.begin(),vec.end()); sort(vec2.begin(),vec2.end());//排序 for(int i=0;i<n-1;i++) { //从最小的数开始找,在排序好的序列中,找相邻的两个数m,n,其中m<n; //如果在原始序列中m的位置大于n,就需要把n移到后面,然后所有大于n的数就都需要移到后面。 if((find(vec.begin(),vec.end(),vec2[i])-find(vec.begin(),vec.end(),vec2[i+1]))>0) { cout<<n-i-1<<endl; return 0; } } cout<<0<<endl; return 0; }
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); sc.nextLine(); String[] s = sc.nextLine().split(" "); int[] arr = new int[n]; int[] brr = new int[n]; int min = Integer.MAX_VALUE; for (int i = 0; i < n; i++) { arr[i] = Integer.parseInt(s[i]); brr[i] = Integer.parseInt(s[i]); min = Math.min(arr[i], min); } int p = 0; Arrays.sort(brr); // 升序 for (int i = 0; i < n; i++) { if(arr[i] == brr[p]) p++; } System.out.println(n - p); } }
先把数组从小到大排列,然后逐次比较sorted[i]和sorted[i+1]在array中的下标,如果i下标大于i+1下标count加1同时对array进行操作 import java.util.*; public class Main{ public static void main(String[] args){ Scanner scan=new Scanner(System.in); while(scan.hasNext()){ int num=scan.nextInt(); int[] array=new int[num]; int[] sorted=new int[num]; for(int i=0;i<num;i++){ array[i]=scan.nextInt(); sorted[i]=array[i]; } int count=0; Arrays.sort(sorted); for(int j=0;j<num-1;j++){ if(index(sorted[j],array)>index(sorted[j+1],array)){ count++; int temp=sorted[j+1]; for (int k=index(sorted[j+1],array);k<array.length-1;k++){ array[k]=array[k+1]; } array[array.length-1]=temp; } } System.out.println(count); } } public static int index(int param,int[] array){ for(int i=0;i<array.length;i++){ if(array[i]==param){ return i; } } return -1; } }
//现在我们的思路是找出有序的最小的一组元素,先找出v1的最小元素,记住值imin和位置back,和前一位置相比 //若该位置在前一位置front之后,令front=back,删除该位置元素,此处必须为“<=”,因为删除元素之后,之后back是可以和front相等的 //若存在back>front,则直接结束 #include<iostream> #include<vector> #include<algorithm> using namespace std; int main(){ int n,m; int cnt = 0; vector<int> v,v2; cin>>n; for(int i = 0;i != n;i++){ cin>>m; v.push_back(m); v2.push_back(m); } sort(v2.begin(),v2.end());//将v2排序 int front = -1; int back; for(int i = 0;i != n;i++){ int imin = 1001; for(int j = 0;j != v.size();j++){ if(v[j] < imin){ imin = v[j]; back = j; } } if(v2[i] == imin){ if(front <= back){ cnt++; front = back; v.erase(v.begin()+back); } else break; } } cout<<n-cnt<<endl; }
//借鉴各位大神的思路 把不需要移动的数字个数记录下来 #include <iostream> #include <vector> #include <algorithm> using namespace std; int main(){ int n,a[50]; int i =0; int count = 0; cin >> n; vector<int> arr; while(n--) { int temp ; cin >> temp; a[i++] = temp; arr.push_back(temp); } sort(arr.begin(),arr.end()); int m = 0; for(int j = 0;j<i;j++) { if(a[j]==arr[m]) { count++; m++; } } cout << i-count << endl; }
if __name__ == '__main__':
#解法1,易理解
n = int(sys.stdin.readline().strip())
alist = map(int,sys.stdin.readline().strip().split(" "))
newlist = sorted(alist)
mdict = {}
org = len(alist)
nmax = org
for i,data in enumerate(alist):
mdict[data] = i
for i in range(org-1):
# 以已排序数组中元素为参照,依次在待排数组中查看相邻元素的小标是否满足“左小右大”原则,不满足的,将大值插入到数组末尾。
if mdict[newlist[i]]>mdict[newlist[i+1]]:
mdict[newlist[i+1]]=nmax
nmax+=1
print nmax-org
#include<iostream> #include<vector> #include<algorithm> #include<map> using namespace std; int main() { int N, temp; cin>>N; vector<int> v; map<int, int> m; for(int i=0; i<N; ++i) { cin>>temp; v.push_back(temp); m[temp]=i; } sort(v.begin(), v.end()); int t=N, count=0; for(int i=0; i<N-1; ++i) { if(m[v[i]]>m[v[i+1]]) { m[v[i+1]]=t++; ++count; } } cout<<count<<endl; }
/*另类解法:*/ #include<iostream> #include<list> intmain() { int N; std::cin >> N; std::list<int>numlist;//创建链表 int answer=0, power = 0, swich;//初始化 for(int i = 0; i != N; ++i) { int number; std::cin >> number; numlist.push_back(number); }//把数存入链表 numlist.reverse();//反转链表 while(numlist.size()>1) { swich = 0; intfirstnum = numlist.front();//获取第一个元素 numlist.pop_front();//删掉第一个元素 for(auto p=numlist.begin();p!=numlist.end();)//遍历链表 { if(*p > firstnum)//比第一个数大? { ++answer;//答案加一 swich = 1;//开关触发 p=numlist.erase(p);//删掉满足条件的点; } else ++p; } if(swich)//如果开关触发 { answer += power;//释放能量 power = 1;//重置能量 } else ++power;//积蓄能量 } std::cout << answer; return 0; }
#include<iostream> #include<string> using namespace std; int main(){ int N, a[50]; cin >> N; for(int i=0;i<N;i++){ cin >> a[i]; } // find longest sorted subarray embedded in the array that starts from the min, // then the min steps is N-N_sorted_subarray // // go through every element, store the first element in the subarray, if the next element // is larger than the first one, then include it in the subarray, if not, reduce the subarray // until it can include this one. Also record the smallest element so far that is not in the subarray, // if coming element is larger than that, then ignore. // Finally, output the length of subarray int asub[50]={-1000}; int j=0; int min_out=1000; asub[0]=a[0]; for(int i=1;i<N;i++){ if(a[i]<=min_out){ while(j>=0 && asub[j]>=a[i]){ min_out=asub[j]; j--; } j++; asub[j]=a[i]; } } cout << N-j-1; return 0; }
//思路是这样的,从最小的值开始找,找到最长的按数组中的值的大小严格出现的最长序列,然后答案就是数组长度-最长序列的长度importjava.util.*;publicclassMain {staticclassp{intval;intindex;publicp(intv,inti){val=v;index=i;}}publicstaticvoidmain(String[] args){Scanner in=newScanner(System.in);intn=in.nextInt();p[] data=newp[n];for(inti=0;i<n;++i){intv=in.nextInt();data[i]=newp(v, i);}Arrays.sort(data,newComparator<p>() {publicintcompare(p o1, p o2) {// TODO Auto-generated method stubreturno1.val-o2.val;}});intlen=1;ints=data[0].index;for(inti=1;i<n;++i){if(data[i].index>s){len++;s=data[i].index;}else{break;}}System.out.println(n-len);in.close();}}
递归,先找到最小数的数组下标,以该元素分为两部分,前一部分是要移动的,并且要找到前一部分中最小的元素min。
然后,从后一部分找比min要大的元素个数,这些也是需要移动的,然后找比min要小的元素,这些元素是待定的,把他们存入另一个数组中,然后以这个数组为递归的新参数,递归调用,直到不需要移动。
#include<iostream> using namespace std; int min(int *a, int n) { int mi = 0; for(int i = 1; i<n; i++) { if( a[mi] >a[i]) mi = i; } return mi; } int dp(int *a, int n) { if(n == 0) return 0; int pos = min(a,n); int y1 = pos; if(pos == 0 ) y1 = dp(a+1, n-1); else { int mi = min(a,pos); int b[n]; int t = 0; for(int i = pos +1; i< n; i++) { if(a[mi] < a[i] ) { y1++; } else { b[t] = a[i]; t++; } } y1 = y1 + dp(b,t); } return y1; } int main() { int n; while(cin>>n) { int a[n]; for(int i = 0; i<n; i++) { cin>>a[i]; } int t = dp(a,n); printf("%d\n", t); } }
//假设数组A=[1,3,2,5,4],先进行排序,变成数组B=[1,2,3,4,5],然后开始顺序检索B数组 //中的数字,会发现2在1后面,3在2前面,所以我们要从3开始重排,因为只能把3移到无序 //数组末端,所以所有数组B在3之后的元素都要进行重排,所以重排次数就是数组大小减去 //第一个重排数在数组B中的序数。 #include <iostream> #include <vector> #include <algorithm> using namespace std; int main(){ int size; vector <int> arr,arr2; cin>>size; int temp=0; for(int i=0;i<size;i++) { cin>>temp; arr.push_back(temp); arr2.push_back(temp); } sort(arr.begin(),arr.end()); int g=0; for(int h;h<size;h++) if(arr2[h]==arr[g]) { g++; continue; } cout<<size-g; return 0; }