中山大学校队选拔赛第二试题试题3【Compressed suffix array】-------2015年2月8日
一:题目大意
本题通过给定三个数组S0,P,S,其中S0是1到2n的一个排列,P具有2n个整数,且满足:
数组S是把数组S0中所有奇数元素全部删除并将所有偶数元素除以2并按照原来的相对顺序进行排列而得。
现在给定数组S和数组P,我们需要反求数组S0。
二:题目分析
我们通过对数组P的递推式分析可知:当数组S0的元素是偶数时,这个元素所对应的Pi的值一定等于i.当数组S0的元素为奇数时,我们可以知道对应的Pi一定不等于i。那么我们可以先对数组P扫一遍,把存在Pi=i的元素全部填好,然后再对数组P重新扫描一遍,把所有奇数位置的元素通过如下公式求得并填好:
最后就是对数组进行输出了。over~
三:AC代码
#include<iostream> using namespace std; int ans[1<<14],s[1<<14],p[1<<14]; int main() { int n; while(cin>>n) { for(int i=0;i<n;i++) cin>>p[i]; for(int i=0;i<n/2;i++) cin>>s[i]; int k=0; for(int i=0;i<n;i++) { if(p[i]==i+1) { ans[i]=s[k++]*2; } } for(int i=0;i<n;i++) { if(p[i]!=i+1) { ans[i]=ans[p[i]-1]-1; } } int i; for( i=0;i<n-1;i++) cout<<ans[i]<<' '; cout<<ans[i]<<endl; } return 0; }
四:总结
本题就是逆向思维的运用,以及对找到数组之间的规律的综合体现。