1. 程式人生 > 實用技巧 >Codeforces 1173 C 思維+模擬

Codeforces 1173 C 思維+模擬

xg

題意

  給相同長度為n的兩個陣列a,b。其中包括1-n和n個0。

  一次操作:可以把a中任意一個數放到b的最右面,然後把b的最前面一個數放到a中。

  問最少多少次操作可以使得b陣列為1,2,3.....n。

思路

  很明顯a陣列不影響結果,只需要分析b陣列即可。且最多隻需要2*n次操作。

如果1-n都在a中,則只需要n個操作。

如果1在b末尾,且其餘數在a中,則需要n-1。(如果存在一些數在b的1的前部分,則需要判斷當需要放這個數到b的末尾的時候,這個數是在a中還是b中)。

  1:如果1在a中,則結果一定大於n,因為一定要把這n個數塞到b中。則只需要判斷b陣列中不為0的數(假如說是bi)在塞了bi個數的時候能不能從b中取出。即找Σ(0,i-(bi-1))。

  2:如果1在b中。則根據1往後能否自成一段單獨判斷,其餘類似模擬即可。

  

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <stack>
#include <set
> #include <vector> // #include <bits/stdc++.h> #define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define sp ' ' #define endl '\n' #define FOR(i,a,b) for( int i = a;i <= b;++i) #define bug cout<<"--------------"<<endl #define P pair<int, int> #define fi first #define
se second #define pb(x) push_back(x) #define ppb() pop_back() #define mp(a,b) make_pair(a,b) #define ms(v,x) memset(v,x,sizeof(v)) #define rep(i,a,b) for(int i=a;i<=b;i++) #define repd(i,a,b) for(int i=a;i>=b;i--) #define sca3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c)) #define sca2(a,b) scanf("%d %d",&(a),&(b)) #define sca(a) scanf("%d",&(a)); #define sca3ll(a,b,c) scanf("%lld %lld %lld",&(a),&(b),&(c)) #define sca2ll(a,b) scanf("%lld %lld",&(a),&(b)) #define scall(a) scanf("%lld",&(a)); using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a, ll b, ll mod){ll sum = 1;while (b) {if (b & 1) {sum = (sum * a) % mod;b--;}b /= 2;a = a * a % mod;}return sum;} const double Pi = acos(-1.0); const double epsilon = Pi/180.0; const int maxn = 2e5+10; int a[maxn],b[maxn]; int main() { //freopen("input.txt", "r", stdin); int n; sca(n); int pos = n+1; rep(i,1,n) sca(a[i]); rep(i,1,n) { sca(b[i]); if(b[i]==1) pos = i; } int flag = 0,nub = n-pos+1,ans1; if(pos == n+1){ int tmp = 0; rep(i,1,n){ if(b[i] == 0) continue; tmp = max(tmp,i-b[i]+1); } printf("%d\n",n+tmp ); return 0; } // bug; int cnt = 0; flag = 0; rep(i,pos,n){ if(b[i] != ++cnt){ flag =1; break; } } if(flag == 1){ int tmp = 0; rep(i,1,n){ if(b[i] == 0) continue; tmp = max(tmp,i-b[i]+1); } printf("%d\n",n+tmp ); } else if(flag == 0){ int tmp = 0; rep(i,1,pos-1){ if(b[i] == 0) continue; if(i > b[i]-(n-pos+1)-1) { tmp = 1;break; } //tmp = max(tmp,i-b[i]+1); } if(tmp == 1) { printf("%d\n",n+pos ); } else printf("%d\n",pos-1 ); } }