codeforce Sorting the Coins

其实这个题看明白了挺简单的。

题目大意: 给你n个不流通的硬币,然后每次替换其中一个,每替换一个就询问一次按照Dima的算法需要几次才能最终没有可以相互交换的coin。

每次替换之后,按照Dima的算法执行时,coin的顺序是不变的,因为题目中说了DIma只可以在心中想,不可以移动coin。

题解:首先要想明白每次执行Dima的算法都会把一个不流通的coin移动到最后面,所以题目就变成了每次替换之后有几个coin没有放在最后面的位置。

变量:p:从后往前第一个不流通的coin的位置,即p后面的coin已经都是流通coin了,需要移动的在前面 初始p=n;

ok:已经放在最后面连续的流通coin的个数,也就是ok=n-p; 初始ok=0;

a[i]:第i次要替换的位置

book[i]:第i个位置上是否已经替换

if(a[i]<p)   如果要替换的coin没放在最后面,那么移动次数 ans=i-ok+1;  这一次的算法的执行数量就是把前面i-ok个都移动回来就是i-ok次,加一是因为不移动为1 然后 boo[a[i]]=1;

if(a[i] == p) 表明这一个放在最后的位置上了,这次移动不用管这个了 book[a[i]]=1;

                  然后往前看,while(book[p]){p--;ok++;}    找下一个p的值,并且更新ok

p是肯定大于a[i] 因为p是可以替换的位置的最后面的值。

第一次和最后一次可以不用管,直接输出1。

AC代码,就20多行,时间复杂度为O(N)

#include<iostream>
using namespace std;
const int maxn = 300005;
int a[maxn],book[maxn];
int n,p,ok;
int main()
{
	cin>>n;
	p=n;
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	printf("1 ");
	for(int i=1;i<n;i++){
		if(a[i]<p){
			printf("%d ",i-ok+1);
			book[a[i]]=1;
		} 
		else if(a[i]==p){
			book[a[i]]=1;
			while(book[p]){ p--;ok++; }
			printf("%d ",i-ok+1);
		}
	}
	printf("1");
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章