网站备案提交管局做营销的一般逛哪些网站
这一题的题意是给出一个乱序序列,要求我们只能用0的位置和其他值的位置进行交换,使得所有的值归到它应有的位置上。
这一题我拿到并没有什么很好的思路,看题解说是贪心,可实际上也不是很明显,我觉得更多的是思维题+贪心+模拟吧,
思路就是记录每一个数字所在的位置,然后按照题意用0所在的位置与该位置本来要放的值的位置进行交换,不断的交换,直至a[0]=0,无法再继续交换了,
然后我们只能选择把0和第一个值和它所对应的位置不相符的位置进行交换,从而让0能继续与其他位置进行交换。
#include <iostream>
#include <limits.h>
#include <cstring>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
int N;
int cnt;
int a[100005];
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>N;for(int i=0;i<N;i++){int k;cin>>k;a[k]=i;}bool flag=1;int k=1;while(flag){while(a[0]!=0){swap(a[0],a[a[0]]);cnt++;}for(;k<N;k++){flag=0;if(a[k]!=k){swap(a[0],a[k]);flag=1;cnt++;break;}}if(flag==0){break;}}cout<<cnt;return 0;}
这里我们用一个flag来标记是否所有的值已经处在正确的位置了。
如果处在,那么flag==0 跳出循环
但是这样写的时间复杂度过高,会有一个测试点不通过。
对此,我们可以对其进行一个优化,先提前统计出来序列中有多少个值和位置不相符(isnot),把循环条件改为isnot>1
即在0与其他位置进行交换的时候,每让一个值交换到另一个符合条件的位置时就isnot–,当isnot==1时,所有的值都处在了合适的位置上了。
完整代码如下:
#include <iostream>
#include <limits.h>
#include <cstring>
#include <queue>
#include <unordered_map>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
int N;
int cnt;
int a[100005];
int isnot;
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>N;for(int i=0;i<N;i++){int k;cin>>k;a[k]=i;}for(int i=0;i<N;i++){if(a[i]!=i){isnot++;}}bool flag=1;int k=1;while(isnot>1){while(a[0]!=0){swap(a[0],a[a[0]]);cnt++;isnot--;}for(;k<N;k++){if(a[k]!=k){swap(a[0],a[k]);cnt++;break;}}}cout<<cnt;return 0;}